<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha256-Z1K5uhUaJXA7Ll0XrZ/0JhX4lAtZFpT6jkKrEDT0drU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.14.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":-1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta property="og:type" content="website">
<meta property="og:title" content="JsyBlog">
<meta property="og:url" content="http://example.com/page/14/index.html">
<meta property="og:site_name" content="JsyBlog">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="SongyangJi">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://example.com/page/14/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/14/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>JsyBlog</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">JsyBlog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">SongyangJi</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">251</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">45</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">109</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/01/04/Hbase/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/01/04/Hbase/" class="post-title-link" itemprop="url">Hbase</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-01-04 02:17:39" itemprop="dateCreated datePublished" datetime="2022-01-04T02:17:39+08:00">2022-01-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-10-09 02:39:05" itemprop="dateModified" datetime="2022-10-09T02:39:05+08:00">2022-10-09</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/NoSQL/" itemprop="url" rel="index"><span itemprop="name">NoSQL</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">brew install hbase</span><br><span class="line">brew install jruby</span><br><span class="line">brew install asciidoctor</span><br></pre></td></tr></table></figure>



<h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew services start hbase</span><br></pre></td></tr></table></figure>



<p><a target="_blank" rel="noopener" href="http://localhost:16010/">http://localhost:16010</a></p>
<h1 id="应用实例"><a href="#应用实例" class="headerlink" title="应用实例"></a>应用实例</h1><h2 id="手机数据"><a href="#手机数据" class="headerlink" title="手机数据"></a>手机数据</h2><ul>
<li>需求</li>
</ul>
<p>有一张数据表，其中包含手机号码字段</p>
<ol>
<li>查询一段时间内固定号码的所有数据 </li>
<li>查询一段时间内所有数据</li>
</ol>
<ul>
<li><p>分析</p>
<p>HBase要想查询快速，只能从rowKey上下手rowKey&#x3D;phoneNum+时间 可以实现目标1，但是目标2很难实现rowKey&#x3D;时间+phoneNum 可以实现目标2，但是目标1很难实现，且数据量越来越大可能导致热点问题 。</p>
</li>
<li><p>解决思路1：牺牲空间换时间，写数据时同时写入两张表，内容一样，只是一张表rowKey&#x3D;phoneNum+时间，另一张表rowKey&#x3D;时间+phoneNum</p>
</li>
<li><p>解决思路2：牺牲部分空间部分时间，两张表，一张全量表，rowKey&#x3D;phoneNum+时间，另一张索引表只存rowKey&#x3D;时间+phoneNum，目标1通过scan全量表就可以实现，目标2先scan索引表然后批量get全量表。</p>
</li>
</ul>
<h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><blockquote>
<p><a target="_blank" rel="noopener" href="https://www.cnblogs.com/scuwangjun/p/11555291.html">https://www.cnblogs.com/scuwangjun/p/11555291.html</a><br><a target="_blank" rel="noopener" href="https://www.cnblogs.com/Chaser-Eagle/p/12008510.html">https://www.cnblogs.com/Chaser-Eagle/p/12008510.html</a></p>
<p><a target="_blank" rel="noopener" href="https://juejin.cn/post/6844903753271754759">一文讲清HBase存储结构</a></p>
</blockquote>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/01/03/Neo4j/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/01/03/Neo4j/" class="post-title-link" itemprop="url">Neo4j</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-01-03 23:47:45" itemprop="dateCreated datePublished" datetime="2022-01-03T23:47:45+08:00">2022-01-03</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-01-04 16:27:37" itemprop="dateModified" datetime="2022-01-04T16:27:37+08:00">2022-01-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/NoSQL/" itemprop="url" rel="index"><span itemprop="name">NoSQL</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><p><a target="_blank" rel="noopener" href="https://neo4j.com/download-center/#community">https://neo4j.com/download-center/#community</a></p>
<h1 id="入门"><a href="#入门" class="headerlink" title="入门"></a>入门</h1><h2 id="Create"><a href="#Create" class="headerlink" title="Create"></a>Create</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br></pre></td><td class="code"><pre><span class="line">CREATE (TheMatrix:Movie &#123;title:&#x27;The Matrix&#x27;, released:1999, tagline:&#x27;Welcome to the Real World&#x27;&#125;)</span><br><span class="line">      CREATE (Keanu:Person &#123;name:&#x27;Keanu Reeves&#x27;, born:1964&#125;)</span><br><span class="line">      CREATE (Carrie:Person &#123;name:&#x27;Carrie-Anne Moss&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE (Laurence:Person &#123;name:&#x27;Laurence Fishburne&#x27;, born:1961&#125;)</span><br><span class="line">      CREATE (Hugo:Person &#123;name:&#x27;Hugo Weaving&#x27;, born:1960&#125;)</span><br><span class="line">      CREATE (LillyW:Person &#123;name:&#x27;Lilly Wachowski&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE (LanaW:Person &#123;name:&#x27;Lana Wachowski&#x27;, born:1965&#125;)</span><br><span class="line">      CREATE (JoelS:Person &#123;name:&#x27;Joel Silver&#x27;, born:1952&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Neo&#x27;]&#125;]-&gt;(TheMatrix),</span><br><span class="line">      (Carrie)-[:ACTED_IN &#123;roles:[&#x27;Trinity&#x27;]&#125;]-&gt;(TheMatrix),</span><br><span class="line">      (Laurence)-[:ACTED_IN &#123;roles:[&#x27;Morpheus&#x27;]&#125;]-&gt;(TheMatrix),</span><br><span class="line">      (Hugo)-[:ACTED_IN &#123;roles:[&#x27;Agent Smith&#x27;]&#125;]-&gt;(TheMatrix),</span><br><span class="line">      (LillyW)-[:DIRECTED]-&gt;(TheMatrix),</span><br><span class="line">      (LanaW)-[:DIRECTED]-&gt;(TheMatrix),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(TheMatrix)</span><br><span class="line"></span><br><span class="line">      CREATE (Emil:Person &#123;name:&quot;Emil Eifrem&quot;, born:1978&#125;)</span><br><span class="line">      CREATE (Emil)-[:ACTED_IN &#123;roles:[&quot;Emil&quot;]&#125;]-&gt;(TheMatrix)</span><br><span class="line"></span><br><span class="line">      CREATE (TheMatrixReloaded:Movie &#123;title:&#x27;The Matrix Reloaded&#x27;, released:2003, tagline:&#x27;Free your mind&#x27;&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Neo&#x27;]&#125;]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (Carrie)-[:ACTED_IN &#123;roles:[&#x27;Trinity&#x27;]&#125;]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (Laurence)-[:ACTED_IN &#123;roles:[&#x27;Morpheus&#x27;]&#125;]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (Hugo)-[:ACTED_IN &#123;roles:[&#x27;Agent Smith&#x27;]&#125;]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (LillyW)-[:DIRECTED]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (LanaW)-[:DIRECTED]-&gt;(TheMatrixReloaded),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(TheMatrixReloaded)</span><br><span class="line"></span><br><span class="line">      CREATE (TheMatrixRevolutions:Movie &#123;title:&#x27;The Matrix Revolutions&#x27;, released:2003, tagline:&#x27;Everything that has a beginning has an end&#x27;&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Neo&#x27;]&#125;]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (Carrie)-[:ACTED_IN &#123;roles:[&#x27;Trinity&#x27;]&#125;]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (Laurence)-[:ACTED_IN &#123;roles:[&#x27;Morpheus&#x27;]&#125;]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (Hugo)-[:ACTED_IN &#123;roles:[&#x27;Agent Smith&#x27;]&#125;]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (LillyW)-[:DIRECTED]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (LanaW)-[:DIRECTED]-&gt;(TheMatrixRevolutions),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(TheMatrixRevolutions)</span><br><span class="line"></span><br><span class="line">      CREATE (TheDevilsAdvocate:Movie &#123;title:&quot;The Devil&#x27;s Advocate&quot;, released:1997, tagline:&#x27;Evil has its winning ways&#x27;&#125;)</span><br><span class="line">      CREATE (Charlize:Person &#123;name:&#x27;Charlize Theron&#x27;, born:1975&#125;)</span><br><span class="line">      CREATE (Al:Person &#123;name:&#x27;Al Pacino&#x27;, born:1940&#125;)</span><br><span class="line">      CREATE (Taylor:Person &#123;name:&#x27;Taylor Hackford&#x27;, born:1944&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Kevin Lomax&#x27;]&#125;]-&gt;(TheDevilsAdvocate),</span><br><span class="line">      (Charlize)-[:ACTED_IN &#123;roles:[&#x27;Mary Ann Lomax&#x27;]&#125;]-&gt;(TheDevilsAdvocate),</span><br><span class="line">      (Al)-[:ACTED_IN &#123;roles:[&#x27;John Milton&#x27;]&#125;]-&gt;(TheDevilsAdvocate),</span><br><span class="line">      (Taylor)-[:DIRECTED]-&gt;(TheDevilsAdvocate)</span><br><span class="line"></span><br><span class="line">      CREATE (AFewGoodMen:Movie &#123;title:&quot;A Few Good Men&quot;, released:1992, tagline:&quot;In the heart of the nation&#x27;s capital, in a courthouse of the U.S. government, one man will stop at nothing to keep his honor, and one will stop at nothing to find the truth.&quot;&#125;)</span><br><span class="line">      CREATE (TomC:Person &#123;name:&#x27;Tom Cruise&#x27;, born:1962&#125;)</span><br><span class="line">      CREATE (JackN:Person &#123;name:&#x27;Jack Nicholson&#x27;, born:1937&#125;)</span><br><span class="line">      CREATE (DemiM:Person &#123;name:&#x27;Demi Moore&#x27;, born:1962&#125;)</span><br><span class="line">      CREATE (KevinB:Person &#123;name:&#x27;Kevin Bacon&#x27;, born:1958&#125;)</span><br><span class="line">      CREATE (KieferS:Person &#123;name:&#x27;Kiefer Sutherland&#x27;, born:1966&#125;)</span><br><span class="line">      CREATE (NoahW:Person &#123;name:&#x27;Noah Wyle&#x27;, born:1971&#125;)</span><br><span class="line">      CREATE (CubaG:Person &#123;name:&#x27;Cuba Gooding Jr.&#x27;, born:1968&#125;)</span><br><span class="line">      CREATE (KevinP:Person &#123;name:&#x27;Kevin Pollak&#x27;, born:1957&#125;)</span><br><span class="line">      CREATE (JTW:Person &#123;name:&#x27;J.T. Walsh&#x27;, born:1943&#125;)</span><br><span class="line">      CREATE (JamesM:Person &#123;name:&#x27;James Marshall&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE (ChristopherG:Person &#123;name:&#x27;Christopher Guest&#x27;, born:1948&#125;)</span><br><span class="line">      CREATE (RobR:Person &#123;name:&#x27;Rob Reiner&#x27;, born:1947&#125;)</span><br><span class="line">      CREATE (AaronS:Person &#123;name:&#x27;Aaron Sorkin&#x27;, born:1961&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomC)-[:ACTED_IN &#123;roles:[&#x27;Lt. Daniel Kaffee&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (JackN)-[:ACTED_IN &#123;roles:[&#x27;Col. Nathan R. Jessup&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (DemiM)-[:ACTED_IN &#123;roles:[&#x27;Lt. Cdr. JoAnne Galloway&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (KevinB)-[:ACTED_IN &#123;roles:[&#x27;Capt. Jack Ross&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (KieferS)-[:ACTED_IN &#123;roles:[&#x27;Lt. Jonathan Kendrick&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (NoahW)-[:ACTED_IN &#123;roles:[&#x27;Cpl. Jeffrey Barnes&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (CubaG)-[:ACTED_IN &#123;roles:[&#x27;Cpl. Carl Hammaker&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (KevinP)-[:ACTED_IN &#123;roles:[&#x27;Lt. Sam Weinberg&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (JTW)-[:ACTED_IN &#123;roles:[&#x27;Lt. Col. Matthew Andrew Markinson&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (JamesM)-[:ACTED_IN &#123;roles:[&#x27;Pfc. Louden Downey&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (ChristopherG)-[:ACTED_IN &#123;roles:[&#x27;Dr. Stone&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (AaronS)-[:ACTED_IN &#123;roles:[&#x27;Man in Bar&#x27;]&#125;]-&gt;(AFewGoodMen),</span><br><span class="line">      (RobR)-[:DIRECTED]-&gt;(AFewGoodMen),</span><br><span class="line">      (AaronS)-[:WROTE]-&gt;(AFewGoodMen)</span><br><span class="line"></span><br><span class="line">      CREATE (TopGun:Movie &#123;title:&quot;Top Gun&quot;, released:1986, tagline:&#x27;I feel the need, the need for speed.&#x27;&#125;)</span><br><span class="line">      CREATE (KellyM:Person &#123;name:&#x27;Kelly McGillis&#x27;, born:1957&#125;)</span><br><span class="line">      CREATE (ValK:Person &#123;name:&#x27;Val Kilmer&#x27;, born:1959&#125;)</span><br><span class="line">      CREATE (AnthonyE:Person &#123;name:&#x27;Anthony Edwards&#x27;, born:1962&#125;)</span><br><span class="line">      CREATE (TomS:Person &#123;name:&#x27;Tom Skerritt&#x27;, born:1933&#125;)</span><br><span class="line">      CREATE (MegR:Person &#123;name:&#x27;Meg Ryan&#x27;, born:1961&#125;)</span><br><span class="line">      CREATE (TonyS:Person &#123;name:&#x27;Tony Scott&#x27;, born:1944&#125;)</span><br><span class="line">      CREATE (JimC:Person &#123;name:&#x27;Jim Cash&#x27;, born:1941&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomC)-[:ACTED_IN &#123;roles:[&#x27;Maverick&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (KellyM)-[:ACTED_IN &#123;roles:[&#x27;Charlie&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (ValK)-[:ACTED_IN &#123;roles:[&#x27;Iceman&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (AnthonyE)-[:ACTED_IN &#123;roles:[&#x27;Goose&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (TomS)-[:ACTED_IN &#123;roles:[&#x27;Viper&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (MegR)-[:ACTED_IN &#123;roles:[&#x27;Carole&#x27;]&#125;]-&gt;(TopGun),</span><br><span class="line">      (TonyS)-[:DIRECTED]-&gt;(TopGun),</span><br><span class="line">      (JimC)-[:WROTE]-&gt;(TopGun)</span><br><span class="line"></span><br><span class="line">      CREATE (JerryMaguire:Movie &#123;title:&#x27;Jerry Maguire&#x27;, released:2000, tagline:&#x27;The rest of his life begins now.&#x27;&#125;)</span><br><span class="line">      CREATE (ReneeZ:Person &#123;name:&#x27;Renee Zellweger&#x27;, born:1969&#125;)</span><br><span class="line">      CREATE (KellyP:Person &#123;name:&#x27;Kelly Preston&#x27;, born:1962&#125;)</span><br><span class="line">      CREATE (JerryO:Person &#123;name:&quot;Jerry O&#x27;Connell&quot;, born:1974&#125;)</span><br><span class="line">      CREATE (JayM:Person &#123;name:&#x27;Jay Mohr&#x27;, born:1970&#125;)</span><br><span class="line">      CREATE (BonnieH:Person &#123;name:&#x27;Bonnie Hunt&#x27;, born:1961&#125;)</span><br><span class="line">      CREATE (ReginaK:Person &#123;name:&#x27;Regina King&#x27;, born:1971&#125;)</span><br><span class="line">      CREATE (JonathanL:Person &#123;name:&#x27;Jonathan Lipnicki&#x27;, born:1996&#125;)</span><br><span class="line">      CREATE (CameronC:Person &#123;name:&#x27;Cameron Crowe&#x27;, born:1957&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomC)-[:ACTED_IN &#123;roles:[&#x27;Jerry Maguire&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (CubaG)-[:ACTED_IN &#123;roles:[&#x27;Rod Tidwell&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (ReneeZ)-[:ACTED_IN &#123;roles:[&#x27;Dorothy Boyd&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (KellyP)-[:ACTED_IN &#123;roles:[&#x27;Avery Bishop&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (JerryO)-[:ACTED_IN &#123;roles:[&#x27;Frank Cushman&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (JayM)-[:ACTED_IN &#123;roles:[&#x27;Bob Sugar&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (BonnieH)-[:ACTED_IN &#123;roles:[&#x27;Laurel Boyd&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (ReginaK)-[:ACTED_IN &#123;roles:[&#x27;Marcee Tidwell&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (JonathanL)-[:ACTED_IN &#123;roles:[&#x27;Ray Boyd&#x27;]&#125;]-&gt;(JerryMaguire),</span><br><span class="line">      (CameronC)-[:DIRECTED]-&gt;(JerryMaguire),</span><br><span class="line">      (CameronC)-[:PRODUCED]-&gt;(JerryMaguire),</span><br><span class="line">      (CameronC)-[:WROTE]-&gt;(JerryMaguire)</span><br><span class="line"></span><br><span class="line">      CREATE (StandByMe:Movie &#123;title:&quot;Stand By Me&quot;, released:1986, tagline:&quot;For some, it&#x27;s the last real taste of innocence, and the first real taste of life. But for everyone, it&#x27;s the time that memories are made of.&quot;&#125;)</span><br><span class="line">      CREATE (RiverP:Person &#123;name:&#x27;River Phoenix&#x27;, born:1970&#125;)</span><br><span class="line">      CREATE (CoreyF:Person &#123;name:&#x27;Corey Feldman&#x27;, born:1971&#125;)</span><br><span class="line">      CREATE (WilW:Person &#123;name:&#x27;Wil Wheaton&#x27;, born:1972&#125;)</span><br><span class="line">      CREATE (JohnC:Person &#123;name:&#x27;John Cusack&#x27;, born:1966&#125;)</span><br><span class="line">      CREATE (MarshallB:Person &#123;name:&#x27;Marshall Bell&#x27;, born:1942&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (WilW)-[:ACTED_IN &#123;roles:[&#x27;Gordie Lachance&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (RiverP)-[:ACTED_IN &#123;roles:[&#x27;Chris Chambers&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (JerryO)-[:ACTED_IN &#123;roles:[&#x27;Vern Tessio&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (CoreyF)-[:ACTED_IN &#123;roles:[&#x27;Teddy Duchamp&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (JohnC)-[:ACTED_IN &#123;roles:[&#x27;Denny Lachance&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (KieferS)-[:ACTED_IN &#123;roles:[&#x27;Ace Merrill&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (MarshallB)-[:ACTED_IN &#123;roles:[&#x27;Mr. Lachance&#x27;]&#125;]-&gt;(StandByMe),</span><br><span class="line">      (RobR)-[:DIRECTED]-&gt;(StandByMe)</span><br><span class="line"></span><br><span class="line">      CREATE (AsGoodAsItGets:Movie &#123;title:&#x27;As Good as It Gets&#x27;, released:1997, tagline:&#x27;A comedy from the heart that goes for the throat.&#x27;&#125;)</span><br><span class="line">      CREATE (HelenH:Person &#123;name:&#x27;Helen Hunt&#x27;, born:1963&#125;)</span><br><span class="line">      CREATE (GregK:Person &#123;name:&#x27;Greg Kinnear&#x27;, born:1963&#125;)</span><br><span class="line">      CREATE (JamesB:Person &#123;name:&#x27;James L. Brooks&#x27;, born:1940&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (JackN)-[:ACTED_IN &#123;roles:[&#x27;Melvin Udall&#x27;]&#125;]-&gt;(AsGoodAsItGets),</span><br><span class="line">      (HelenH)-[:ACTED_IN &#123;roles:[&#x27;Carol Connelly&#x27;]&#125;]-&gt;(AsGoodAsItGets),</span><br><span class="line">      (GregK)-[:ACTED_IN &#123;roles:[&#x27;Simon Bishop&#x27;]&#125;]-&gt;(AsGoodAsItGets),</span><br><span class="line">      (CubaG)-[:ACTED_IN &#123;roles:[&#x27;Frank Sachs&#x27;]&#125;]-&gt;(AsGoodAsItGets),</span><br><span class="line">      (JamesB)-[:DIRECTED]-&gt;(AsGoodAsItGets)</span><br><span class="line"></span><br><span class="line">      CREATE (WhatDreamsMayCome:Movie &#123;title:&#x27;What Dreams May Come&#x27;, released:1998, tagline:&#x27;After life there is more. The end is just the beginning.&#x27;&#125;)</span><br><span class="line">      CREATE (AnnabellaS:Person &#123;name:&#x27;Annabella Sciorra&#x27;, born:1960&#125;)</span><br><span class="line">      CREATE (MaxS:Person &#123;name:&#x27;Max von Sydow&#x27;, born:1929&#125;)</span><br><span class="line">      CREATE (WernerH:Person &#123;name:&#x27;Werner Herzog&#x27;, born:1942&#125;)</span><br><span class="line">      CREATE (Robin:Person &#123;name:&#x27;Robin Williams&#x27;, born:1951&#125;)</span><br><span class="line">      CREATE (VincentW:Person &#123;name:&#x27;Vincent Ward&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Robin)-[:ACTED_IN &#123;roles:[&#x27;Chris Nielsen&#x27;]&#125;]-&gt;(WhatDreamsMayCome),</span><br><span class="line">      (CubaG)-[:ACTED_IN &#123;roles:[&#x27;Albert Lewis&#x27;]&#125;]-&gt;(WhatDreamsMayCome),</span><br><span class="line">      (AnnabellaS)-[:ACTED_IN &#123;roles:[&#x27;Annie Collins-Nielsen&#x27;]&#125;]-&gt;(WhatDreamsMayCome),</span><br><span class="line">      (MaxS)-[:ACTED_IN &#123;roles:[&#x27;The Tracker&#x27;]&#125;]-&gt;(WhatDreamsMayCome),</span><br><span class="line">      (WernerH)-[:ACTED_IN &#123;roles:[&#x27;The Face&#x27;]&#125;]-&gt;(WhatDreamsMayCome),</span><br><span class="line">      (VincentW)-[:DIRECTED]-&gt;(WhatDreamsMayCome)</span><br><span class="line"></span><br><span class="line">      CREATE (SnowFallingonCedars:Movie &#123;title:&#x27;Snow Falling on Cedars&#x27;, released:1999, tagline:&#x27;First loves last. Forever.&#x27;&#125;)</span><br><span class="line">      CREATE (EthanH:Person &#123;name:&#x27;Ethan Hawke&#x27;, born:1970&#125;)</span><br><span class="line">      CREATE (RickY:Person &#123;name:&#x27;Rick Yune&#x27;, born:1971&#125;)</span><br><span class="line">      CREATE (JamesC:Person &#123;name:&#x27;James Cromwell&#x27;, born:1940&#125;)</span><br><span class="line">      CREATE (ScottH:Person &#123;name:&#x27;Scott Hicks&#x27;, born:1953&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (EthanH)-[:ACTED_IN &#123;roles:[&#x27;Ishmael Chambers&#x27;]&#125;]-&gt;(SnowFallingonCedars),</span><br><span class="line">      (RickY)-[:ACTED_IN &#123;roles:[&#x27;Kazuo Miyamoto&#x27;]&#125;]-&gt;(SnowFallingonCedars),</span><br><span class="line">      (MaxS)-[:ACTED_IN &#123;roles:[&#x27;Nels Gudmundsson&#x27;]&#125;]-&gt;(SnowFallingonCedars),</span><br><span class="line">      (JamesC)-[:ACTED_IN &#123;roles:[&#x27;Judge Fielding&#x27;]&#125;]-&gt;(SnowFallingonCedars),</span><br><span class="line">      (ScottH)-[:DIRECTED]-&gt;(SnowFallingonCedars)</span><br><span class="line"></span><br><span class="line">      CREATE (YouveGotMail:Movie &#123;title:&quot;You&#x27;ve Got Mail&quot;, released:1998, tagline:&#x27;At odds in life... in love on-line.&#x27;&#125;)</span><br><span class="line">      CREATE (ParkerP:Person &#123;name:&#x27;Parker Posey&#x27;, born:1968&#125;)</span><br><span class="line">      CREATE (DaveC:Person &#123;name:&#x27;Dave Chappelle&#x27;, born:1973&#125;)</span><br><span class="line">      CREATE (SteveZ:Person &#123;name:&#x27;Steve Zahn&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE (TomH:Person &#123;name:&#x27;Tom Hanks&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE (NoraE:Person &#123;name:&#x27;Nora Ephron&#x27;, born:1941&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Joe Fox&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (MegR)-[:ACTED_IN &#123;roles:[&#x27;Kathleen Kelly&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (GregK)-[:ACTED_IN &#123;roles:[&#x27;Frank Navasky&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (ParkerP)-[:ACTED_IN &#123;roles:[&#x27;Patricia Eden&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (DaveC)-[:ACTED_IN &#123;roles:[&#x27;Kevin Jackson&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (SteveZ)-[:ACTED_IN &#123;roles:[&#x27;George Pappas&#x27;]&#125;]-&gt;(YouveGotMail),</span><br><span class="line">      (NoraE)-[:DIRECTED]-&gt;(YouveGotMail)</span><br><span class="line"></span><br><span class="line">      CREATE (SleeplessInSeattle:Movie &#123;title:&#x27;Sleepless in Seattle&#x27;, released:1993, tagline:&#x27;What if someone you never met, someone you never saw, someone you never knew was the only someone for you?&#x27;&#125;)</span><br><span class="line">      CREATE (RitaW:Person &#123;name:&#x27;Rita Wilson&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE (BillPull:Person &#123;name:&#x27;Bill Pullman&#x27;, born:1953&#125;)</span><br><span class="line">      CREATE (VictorG:Person &#123;name:&#x27;Victor Garber&#x27;, born:1949&#125;)</span><br><span class="line">      CREATE (RosieO:Person &#123;name:&quot;Rosie O&#x27;Donnell&quot;, born:1962&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Sam Baldwin&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (MegR)-[:ACTED_IN &#123;roles:[&#x27;Annie Reed&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (RitaW)-[:ACTED_IN &#123;roles:[&#x27;Suzy&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (BillPull)-[:ACTED_IN &#123;roles:[&#x27;Walter&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (VictorG)-[:ACTED_IN &#123;roles:[&#x27;Greg&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (RosieO)-[:ACTED_IN &#123;roles:[&#x27;Becky&#x27;]&#125;]-&gt;(SleeplessInSeattle),</span><br><span class="line">      (NoraE)-[:DIRECTED]-&gt;(SleeplessInSeattle)</span><br><span class="line"></span><br><span class="line">      CREATE (JoeVersustheVolcano:Movie &#123;title:&#x27;Joe Versus the Volcano&#x27;, released:1990, tagline:&#x27;A story of love, lava and burning desire.&#x27;&#125;)</span><br><span class="line">      CREATE (JohnS:Person &#123;name:&#x27;John Patrick Stanley&#x27;, born:1950&#125;)</span><br><span class="line">      CREATE (Nathan:Person &#123;name:&#x27;Nathan Lane&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Joe Banks&#x27;]&#125;]-&gt;(JoeVersustheVolcano),</span><br><span class="line">      (MegR)-[:ACTED_IN &#123;roles:[&#x27;DeDe&#x27;, &#x27;Angelica Graynamore&#x27;, &#x27;Patricia Graynamore&#x27;]&#125;]-&gt;(JoeVersustheVolcano),</span><br><span class="line">      (Nathan)-[:ACTED_IN &#123;roles:[&#x27;Baw&#x27;]&#125;]-&gt;(JoeVersustheVolcano),</span><br><span class="line">      (JohnS)-[:DIRECTED]-&gt;(JoeVersustheVolcano)</span><br><span class="line"></span><br><span class="line">      CREATE (WhenHarryMetSally:Movie &#123;title:&#x27;When Harry Met Sally&#x27;, released:1998, tagline:&#x27;Can two friends sleep together and still love each other in the morning?&#x27;&#125;)</span><br><span class="line">      CREATE (BillyC:Person &#123;name:&#x27;Billy Crystal&#x27;, born:1948&#125;)</span><br><span class="line">      CREATE (CarrieF:Person &#123;name:&#x27;Carrie Fisher&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE (BrunoK:Person &#123;name:&#x27;Bruno Kirby&#x27;, born:1949&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (BillyC)-[:ACTED_IN &#123;roles:[&#x27;Harry Burns&#x27;]&#125;]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (MegR)-[:ACTED_IN &#123;roles:[&#x27;Sally Albright&#x27;]&#125;]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (CarrieF)-[:ACTED_IN &#123;roles:[&#x27;Marie&#x27;]&#125;]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (BrunoK)-[:ACTED_IN &#123;roles:[&#x27;Jess&#x27;]&#125;]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (RobR)-[:DIRECTED]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (RobR)-[:PRODUCED]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (NoraE)-[:PRODUCED]-&gt;(WhenHarryMetSally),</span><br><span class="line">      (NoraE)-[:WROTE]-&gt;(WhenHarryMetSally)</span><br><span class="line"></span><br><span class="line">      CREATE (ThatThingYouDo:Movie &#123;title:&#x27;That Thing You Do&#x27;, released:1996, tagline:&#x27;In every life there comes a time when that thing you dream becomes that thing you do&#x27;&#125;)</span><br><span class="line">      CREATE (LivT:Person &#123;name:&#x27;Liv Tyler&#x27;, born:1977&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Mr. White&#x27;]&#125;]-&gt;(ThatThingYouDo),</span><br><span class="line">      (LivT)-[:ACTED_IN &#123;roles:[&#x27;Faye Dolan&#x27;]&#125;]-&gt;(ThatThingYouDo),</span><br><span class="line">      (Charlize)-[:ACTED_IN &#123;roles:[&#x27;Tina&#x27;]&#125;]-&gt;(ThatThingYouDo),</span><br><span class="line">      (TomH)-[:DIRECTED]-&gt;(ThatThingYouDo)</span><br><span class="line"></span><br><span class="line">      CREATE (TheReplacements:Movie &#123;title:&#x27;The Replacements&#x27;, released:2000, tagline:&#x27;Pain heals, Chicks dig scars... Glory lasts forever&#x27;&#125;)</span><br><span class="line">      CREATE (Brooke:Person &#123;name:&#x27;Brooke Langton&#x27;, born:1970&#125;)</span><br><span class="line">      CREATE (Gene:Person &#123;name:&#x27;Gene Hackman&#x27;, born:1930&#125;)</span><br><span class="line">      CREATE (Orlando:Person &#123;name:&#x27;Orlando Jones&#x27;, born:1968&#125;)</span><br><span class="line">      CREATE (Howard:Person &#123;name:&#x27;Howard Deutch&#x27;, born:1950&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Shane Falco&#x27;]&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (Brooke)-[:ACTED_IN &#123;roles:[&#x27;Annabelle Farrell&#x27;]&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (Gene)-[:ACTED_IN &#123;roles:[&#x27;Jimmy McGinty&#x27;]&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (Orlando)-[:ACTED_IN &#123;roles:[&#x27;Clifford Franklin&#x27;]&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (Howard)-[:DIRECTED]-&gt;(TheReplacements)</span><br><span class="line"></span><br><span class="line">      CREATE (RescueDawn:Movie &#123;title:&#x27;RescueDawn&#x27;, released:2006, tagline:&quot;Based on the extraordinary true story of one man&#x27;s fight for freedom&quot;&#125;)</span><br><span class="line">      CREATE (ChristianB:Person &#123;name:&#x27;Christian Bale&#x27;, born:1974&#125;)</span><br><span class="line">      CREATE (ZachG:Person &#123;name:&#x27;Zach Grenier&#x27;, born:1954&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (MarshallB)-[:ACTED_IN &#123;roles:[&#x27;Admiral&#x27;]&#125;]-&gt;(RescueDawn),</span><br><span class="line">      (ChristianB)-[:ACTED_IN &#123;roles:[&#x27;Dieter Dengler&#x27;]&#125;]-&gt;(RescueDawn),</span><br><span class="line">      (ZachG)-[:ACTED_IN &#123;roles:[&#x27;Squad Leader&#x27;]&#125;]-&gt;(RescueDawn),</span><br><span class="line">      (SteveZ)-[:ACTED_IN &#123;roles:[&#x27;Duane&#x27;]&#125;]-&gt;(RescueDawn),</span><br><span class="line">      (WernerH)-[:DIRECTED]-&gt;(RescueDawn)</span><br><span class="line"></span><br><span class="line">      CREATE (TheBirdcage:Movie &#123;title:&#x27;The Birdcage&#x27;, released:1996, tagline:&#x27;Come as you are&#x27;&#125;)</span><br><span class="line">      CREATE (MikeN:Person &#123;name:&#x27;Mike Nichols&#x27;, born:1931&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Robin)-[:ACTED_IN &#123;roles:[&#x27;Armand Goldman&#x27;]&#125;]-&gt;(TheBirdcage),</span><br><span class="line">      (Nathan)-[:ACTED_IN &#123;roles:[&#x27;Albert Goldman&#x27;]&#125;]-&gt;(TheBirdcage),</span><br><span class="line">      (Gene)-[:ACTED_IN &#123;roles:[&#x27;Sen. Kevin Keeley&#x27;]&#125;]-&gt;(TheBirdcage),</span><br><span class="line">      (MikeN)-[:DIRECTED]-&gt;(TheBirdcage)</span><br><span class="line"></span><br><span class="line">      CREATE (Unforgiven:Movie &#123;title:&#x27;Unforgiven&#x27;, released:1992, tagline:&quot;It&#x27;s a hell of a thing, killing a man&quot;&#125;)</span><br><span class="line">      CREATE (RichardH:Person &#123;name:&#x27;Richard Harris&#x27;, born:1930&#125;)</span><br><span class="line">      CREATE (ClintE:Person &#123;name:&#x27;Clint Eastwood&#x27;, born:1930&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (RichardH)-[:ACTED_IN &#123;roles:[&#x27;English Bob&#x27;]&#125;]-&gt;(Unforgiven),</span><br><span class="line">      (ClintE)-[:ACTED_IN &#123;roles:[&#x27;Bill Munny&#x27;]&#125;]-&gt;(Unforgiven),</span><br><span class="line">      (Gene)-[:ACTED_IN &#123;roles:[&#x27;Little Bill Daggett&#x27;]&#125;]-&gt;(Unforgiven),</span><br><span class="line">      (ClintE)-[:DIRECTED]-&gt;(Unforgiven)</span><br><span class="line"></span><br><span class="line">      CREATE (JohnnyMnemonic:Movie &#123;title:&#x27;Johnny Mnemonic&#x27;, released:1995, tagline:&#x27;The hottest data on earth. In the coolest head in town&#x27;&#125;)</span><br><span class="line">      CREATE (Takeshi:Person &#123;name:&#x27;Takeshi Kitano&#x27;, born:1947&#125;)</span><br><span class="line">      CREATE (Dina:Person &#123;name:&#x27;Dina Meyer&#x27;, born:1968&#125;)</span><br><span class="line">      CREATE (IceT:Person &#123;name:&#x27;Ice-T&#x27;, born:1958&#125;)</span><br><span class="line">      CREATE (RobertL:Person &#123;name:&#x27;Robert Longo&#x27;, born:1953&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Johnny Mnemonic&#x27;]&#125;]-&gt;(JohnnyMnemonic),</span><br><span class="line">      (Takeshi)-[:ACTED_IN &#123;roles:[&#x27;Takahashi&#x27;]&#125;]-&gt;(JohnnyMnemonic),</span><br><span class="line">      (Dina)-[:ACTED_IN &#123;roles:[&#x27;Jane&#x27;]&#125;]-&gt;(JohnnyMnemonic),</span><br><span class="line">      (IceT)-[:ACTED_IN &#123;roles:[&#x27;J-Bone&#x27;]&#125;]-&gt;(JohnnyMnemonic),</span><br><span class="line">      (RobertL)-[:DIRECTED]-&gt;(JohnnyMnemonic)</span><br><span class="line"></span><br><span class="line">      CREATE (CloudAtlas:Movie &#123;title:&#x27;Cloud Atlas&#x27;, released:2012, tagline:&#x27;Everything is connected&#x27;&#125;)</span><br><span class="line">      CREATE (HalleB:Person &#123;name:&#x27;Halle Berry&#x27;, born:1966&#125;)</span><br><span class="line">      CREATE (JimB:Person &#123;name:&#x27;Jim Broadbent&#x27;, born:1949&#125;)</span><br><span class="line">      CREATE (TomT:Person &#123;name:&#x27;Tom Tykwer&#x27;, born:1965&#125;)</span><br><span class="line">      CREATE (DavidMitchell:Person &#123;name:&#x27;David Mitchell&#x27;, born:1969&#125;)</span><br><span class="line">      CREATE (StefanArndt:Person &#123;name:&#x27;Stefan Arndt&#x27;, born:1961&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Zachry&#x27;, &#x27;Dr. Henry Goose&#x27;, &#x27;Isaac Sachs&#x27;, &#x27;Dermot Hoggins&#x27;]&#125;]-&gt;(CloudAtlas),</span><br><span class="line">      (Hugo)-[:ACTED_IN &#123;roles:[&#x27;Bill Smoke&#x27;, &#x27;Haskell Moore&#x27;, &#x27;Tadeusz Kesselring&#x27;, &#x27;Nurse Noakes&#x27;, &#x27;Boardman Mephi&#x27;, &#x27;Old Georgie&#x27;]&#125;]-&gt;(CloudAtlas),</span><br><span class="line">      (HalleB)-[:ACTED_IN &#123;roles:[&#x27;Luisa Rey&#x27;, &#x27;Jocasta Ayrs&#x27;, &#x27;Ovid&#x27;, &#x27;Meronym&#x27;]&#125;]-&gt;(CloudAtlas),</span><br><span class="line">      (JimB)-[:ACTED_IN &#123;roles:[&#x27;Vyvyan Ayrs&#x27;, &#x27;Captain Molyneux&#x27;, &#x27;Timothy Cavendish&#x27;]&#125;]-&gt;(CloudAtlas),</span><br><span class="line">      (TomT)-[:DIRECTED]-&gt;(CloudAtlas),</span><br><span class="line">      (LillyW)-[:DIRECTED]-&gt;(CloudAtlas),</span><br><span class="line">      (LanaW)-[:DIRECTED]-&gt;(CloudAtlas),</span><br><span class="line">      (DavidMitchell)-[:WROTE]-&gt;(CloudAtlas),</span><br><span class="line">      (StefanArndt)-[:PRODUCED]-&gt;(CloudAtlas)</span><br><span class="line"></span><br><span class="line">      CREATE (TheDaVinciCode:Movie &#123;title:&#x27;The Da Vinci Code&#x27;, released:2006, tagline:&#x27;Break The Codes&#x27;&#125;)</span><br><span class="line">      CREATE (IanM:Person &#123;name:&#x27;Ian McKellen&#x27;, born:1939&#125;)</span><br><span class="line">      CREATE (AudreyT:Person &#123;name:&#x27;Audrey Tautou&#x27;, born:1976&#125;)</span><br><span class="line">      CREATE (PaulB:Person &#123;name:&#x27;Paul Bettany&#x27;, born:1971&#125;)</span><br><span class="line">      CREATE (RonH:Person &#123;name:&#x27;Ron Howard&#x27;, born:1954&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Dr. Robert Langdon&#x27;]&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (IanM)-[:ACTED_IN &#123;roles:[&#x27;Sir Leight Teabing&#x27;]&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (AudreyT)-[:ACTED_IN &#123;roles:[&#x27;Sophie Neveu&#x27;]&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (PaulB)-[:ACTED_IN &#123;roles:[&#x27;Silas&#x27;]&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (RonH)-[:DIRECTED]-&gt;(TheDaVinciCode)</span><br><span class="line"></span><br><span class="line">      CREATE (VforVendetta:Movie &#123;title:&#x27;V for Vendetta&#x27;, released:2006, tagline:&#x27;Freedom! Forever!&#x27;&#125;)</span><br><span class="line">      CREATE (NatalieP:Person &#123;name:&#x27;Natalie Portman&#x27;, born:1981&#125;)</span><br><span class="line">      CREATE (StephenR:Person &#123;name:&#x27;Stephen Rea&#x27;, born:1946&#125;)</span><br><span class="line">      CREATE (JohnH:Person &#123;name:&#x27;John Hurt&#x27;, born:1940&#125;)</span><br><span class="line">      CREATE (BenM:Person &#123;name: &#x27;Ben Miles&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Hugo)-[:ACTED_IN &#123;roles:[&#x27;V&#x27;]&#125;]-&gt;(VforVendetta),</span><br><span class="line">      (NatalieP)-[:ACTED_IN &#123;roles:[&#x27;Evey Hammond&#x27;]&#125;]-&gt;(VforVendetta),</span><br><span class="line">      (StephenR)-[:ACTED_IN &#123;roles:[&#x27;Eric Finch&#x27;]&#125;]-&gt;(VforVendetta),</span><br><span class="line">      (JohnH)-[:ACTED_IN &#123;roles:[&#x27;High Chancellor Adam Sutler&#x27;]&#125;]-&gt;(VforVendetta),</span><br><span class="line">      (BenM)-[:ACTED_IN &#123;roles:[&#x27;Dascomb&#x27;]&#125;]-&gt;(VforVendetta),</span><br><span class="line">      (JamesM)-[:DIRECTED]-&gt;(VforVendetta),</span><br><span class="line">      (LillyW)-[:PRODUCED]-&gt;(VforVendetta),</span><br><span class="line">      (LanaW)-[:PRODUCED]-&gt;(VforVendetta),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(VforVendetta),</span><br><span class="line">      (LillyW)-[:WROTE]-&gt;(VforVendetta),</span><br><span class="line">      (LanaW)-[:WROTE]-&gt;(VforVendetta)</span><br><span class="line"></span><br><span class="line">      CREATE (SpeedRacer:Movie &#123;title:&#x27;Speed Racer&#x27;, released:2008, tagline:&#x27;Speed has no limits&#x27;&#125;)</span><br><span class="line">      CREATE (EmileH:Person &#123;name:&#x27;Emile Hirsch&#x27;, born:1985&#125;)</span><br><span class="line">      CREATE (JohnG:Person &#123;name:&#x27;John Goodman&#x27;, born:1960&#125;)</span><br><span class="line">      CREATE (SusanS:Person &#123;name:&#x27;Susan Sarandon&#x27;, born:1946&#125;)</span><br><span class="line">      CREATE (MatthewF:Person &#123;name:&#x27;Matthew Fox&#x27;, born:1966&#125;)</span><br><span class="line">      CREATE (ChristinaR:Person &#123;name:&#x27;Christina Ricci&#x27;, born:1980&#125;)</span><br><span class="line">      CREATE (Rain:Person &#123;name:&#x27;Rain&#x27;, born:1982&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (EmileH)-[:ACTED_IN &#123;roles:[&#x27;Speed Racer&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (JohnG)-[:ACTED_IN &#123;roles:[&#x27;Pops&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (SusanS)-[:ACTED_IN &#123;roles:[&#x27;Mom&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (MatthewF)-[:ACTED_IN &#123;roles:[&#x27;Racer X&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (ChristinaR)-[:ACTED_IN &#123;roles:[&#x27;Trixie&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (Rain)-[:ACTED_IN &#123;roles:[&#x27;Taejo Togokahn&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (BenM)-[:ACTED_IN &#123;roles:[&#x27;Cass Jones&#x27;]&#125;]-&gt;(SpeedRacer),</span><br><span class="line">      (LillyW)-[:DIRECTED]-&gt;(SpeedRacer),</span><br><span class="line">      (LanaW)-[:DIRECTED]-&gt;(SpeedRacer),</span><br><span class="line">      (LillyW)-[:WROTE]-&gt;(SpeedRacer),</span><br><span class="line">      (LanaW)-[:WROTE]-&gt;(SpeedRacer),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(SpeedRacer)</span><br><span class="line"></span><br><span class="line">      CREATE (NinjaAssassin:Movie &#123;title:&#x27;Ninja Assassin&#x27;, released:2009, tagline:&#x27;Prepare to enter a secret world of assassins&#x27;&#125;)</span><br><span class="line">      CREATE (NaomieH:Person &#123;name:&#x27;Naomie Harris&#x27;&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Rain)-[:ACTED_IN &#123;roles:[&#x27;Raizo&#x27;]&#125;]-&gt;(NinjaAssassin),</span><br><span class="line">      (NaomieH)-[:ACTED_IN &#123;roles:[&#x27;Mika Coretti&#x27;]&#125;]-&gt;(NinjaAssassin),</span><br><span class="line">      (RickY)-[:ACTED_IN &#123;roles:[&#x27;Takeshi&#x27;]&#125;]-&gt;(NinjaAssassin),</span><br><span class="line">      (BenM)-[:ACTED_IN &#123;roles:[&#x27;Ryan Maslow&#x27;]&#125;]-&gt;(NinjaAssassin),</span><br><span class="line">      (JamesM)-[:DIRECTED]-&gt;(NinjaAssassin),</span><br><span class="line">      (LillyW)-[:PRODUCED]-&gt;(NinjaAssassin),</span><br><span class="line">      (LanaW)-[:PRODUCED]-&gt;(NinjaAssassin),</span><br><span class="line">      (JoelS)-[:PRODUCED]-&gt;(NinjaAssassin)</span><br><span class="line"></span><br><span class="line">      CREATE (TheGreenMile:Movie &#123;title:&#x27;The Green Mile&#x27;, released:1999, tagline:&quot;Walk a mile you&#x27;ll never forget.&quot;&#125;)</span><br><span class="line">      CREATE (MichaelD:Person &#123;name:&#x27;Michael Clarke Duncan&#x27;, born:1957&#125;)</span><br><span class="line">      CREATE (DavidM:Person &#123;name:&#x27;David Morse&#x27;, born:1953&#125;)</span><br><span class="line">      CREATE (SamR:Person &#123;name:&#x27;Sam Rockwell&#x27;, born:1968&#125;)</span><br><span class="line">      CREATE (GaryS:Person &#123;name:&#x27;Gary Sinise&#x27;, born:1955&#125;)</span><br><span class="line">      CREATE (PatriciaC:Person &#123;name:&#x27;Patricia Clarkson&#x27;, born:1959&#125;)</span><br><span class="line">      CREATE (FrankD:Person &#123;name:&#x27;Frank Darabont&#x27;, born:1959&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Paul Edgecomb&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (MichaelD)-[:ACTED_IN &#123;roles:[&#x27;John Coffey&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (DavidM)-[:ACTED_IN &#123;roles:[&#x27;Brutus &quot;Brutal&quot; Howell&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (BonnieH)-[:ACTED_IN &#123;roles:[&#x27;Jan Edgecomb&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (JamesC)-[:ACTED_IN &#123;roles:[&#x27;Warden Hal Moores&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (SamR)-[:ACTED_IN &#123;roles:[&#x27;&quot;Wild Bill&quot; Wharton&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (GaryS)-[:ACTED_IN &#123;roles:[&#x27;Burt Hammersmith&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (PatriciaC)-[:ACTED_IN &#123;roles:[&#x27;Melinda Moores&#x27;]&#125;]-&gt;(TheGreenMile),</span><br><span class="line">      (FrankD)-[:DIRECTED]-&gt;(TheGreenMile)</span><br><span class="line"></span><br><span class="line">      CREATE (FrostNixon:Movie &#123;title:&#x27;Frost/Nixon&#x27;, released:2008, tagline:&#x27;400 million people were waiting for the truth.&#x27;&#125;)</span><br><span class="line">      CREATE (FrankL:Person &#123;name:&#x27;Frank Langella&#x27;, born:1938&#125;)</span><br><span class="line">      CREATE (MichaelS:Person &#123;name:&#x27;Michael Sheen&#x27;, born:1969&#125;)</span><br><span class="line">      CREATE (OliverP:Person &#123;name:&#x27;Oliver Platt&#x27;, born:1960&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (FrankL)-[:ACTED_IN &#123;roles:[&#x27;Richard Nixon&#x27;]&#125;]-&gt;(FrostNixon),</span><br><span class="line">      (MichaelS)-[:ACTED_IN &#123;roles:[&#x27;David Frost&#x27;]&#125;]-&gt;(FrostNixon),</span><br><span class="line">      (KevinB)-[:ACTED_IN &#123;roles:[&#x27;Jack Brennan&#x27;]&#125;]-&gt;(FrostNixon),</span><br><span class="line">      (OliverP)-[:ACTED_IN &#123;roles:[&#x27;Bob Zelnick&#x27;]&#125;]-&gt;(FrostNixon),</span><br><span class="line">      (SamR)-[:ACTED_IN &#123;roles:[&#x27;James Reston, Jr.&#x27;]&#125;]-&gt;(FrostNixon),</span><br><span class="line">      (RonH)-[:DIRECTED]-&gt;(FrostNixon)</span><br><span class="line"></span><br><span class="line">      CREATE (Hoffa:Movie &#123;title:&#x27;Hoffa&#x27;, released:1992, tagline:&quot;He didn&#x27;t want law. He wanted justice.&quot;&#125;)</span><br><span class="line">      CREATE (DannyD:Person &#123;name:&#x27;Danny DeVito&#x27;, born:1944&#125;)</span><br><span class="line">      CREATE (JohnR:Person &#123;name:&#x27;John C. Reilly&#x27;, born:1965&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (JackN)-[:ACTED_IN &#123;roles:[&#x27;Hoffa&#x27;]&#125;]-&gt;(Hoffa),</span><br><span class="line">      (DannyD)-[:ACTED_IN &#123;roles:[&#x27;Robert &quot;Bobby&quot; Ciaro&#x27;]&#125;]-&gt;(Hoffa),</span><br><span class="line">      (JTW)-[:ACTED_IN &#123;roles:[&#x27;Frank Fitzsimmons&#x27;]&#125;]-&gt;(Hoffa),</span><br><span class="line">      (JohnR)-[:ACTED_IN &#123;roles:[&#x27;Peter &quot;Pete&quot; Connelly&#x27;]&#125;]-&gt;(Hoffa),</span><br><span class="line">      (DannyD)-[:DIRECTED]-&gt;(Hoffa)</span><br><span class="line"></span><br><span class="line">      CREATE (Apollo13:Movie &#123;title:&#x27;Apollo 13&#x27;, released:1995, tagline:&#x27;Houston, we have a problem.&#x27;&#125;)</span><br><span class="line">      CREATE (EdH:Person &#123;name:&#x27;Ed Harris&#x27;, born:1950&#125;)</span><br><span class="line">      CREATE (BillPax:Person &#123;name:&#x27;Bill Paxton&#x27;, born:1955&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Jim Lovell&#x27;]&#125;]-&gt;(Apollo13),</span><br><span class="line">      (KevinB)-[:ACTED_IN &#123;roles:[&#x27;Jack Swigert&#x27;]&#125;]-&gt;(Apollo13),</span><br><span class="line">      (EdH)-[:ACTED_IN &#123;roles:[&#x27;Gene Kranz&#x27;]&#125;]-&gt;(Apollo13),</span><br><span class="line">      (BillPax)-[:ACTED_IN &#123;roles:[&#x27;Fred Haise&#x27;]&#125;]-&gt;(Apollo13),</span><br><span class="line">      (GaryS)-[:ACTED_IN &#123;roles:[&#x27;Ken Mattingly&#x27;]&#125;]-&gt;(Apollo13),</span><br><span class="line">      (RonH)-[:DIRECTED]-&gt;(Apollo13)</span><br><span class="line"></span><br><span class="line">      CREATE (Twister:Movie &#123;title:&#x27;Twister&#x27;, released:1996, tagline:&quot;Don&#x27;t Breathe. Don&#x27;t Look Back.&quot;&#125;)</span><br><span class="line">      CREATE (PhilipH:Person &#123;name:&#x27;Philip Seymour Hoffman&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE (JanB:Person &#123;name:&#x27;Jan de Bont&#x27;, born:1943&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (BillPax)-[:ACTED_IN &#123;roles:[&#x27;Bill Harding&#x27;]&#125;]-&gt;(Twister),</span><br><span class="line">      (HelenH)-[:ACTED_IN &#123;roles:[&#x27;Dr. Jo Harding&#x27;]&#125;]-&gt;(Twister),</span><br><span class="line">      (ZachG)-[:ACTED_IN &#123;roles:[&#x27;Eddie&#x27;]&#125;]-&gt;(Twister),</span><br><span class="line">      (PhilipH)-[:ACTED_IN &#123;roles:[&#x27;Dustin &quot;Dusty&quot; Davis&#x27;]&#125;]-&gt;(Twister),</span><br><span class="line">      (JanB)-[:DIRECTED]-&gt;(Twister)</span><br><span class="line"></span><br><span class="line">      CREATE (CastAway:Movie &#123;title:&#x27;Cast Away&#x27;, released:2000, tagline:&#x27;At the edge of the world, his journey begins.&#x27;&#125;)</span><br><span class="line">      CREATE (RobertZ:Person &#123;name:&#x27;Robert Zemeckis&#x27;, born:1951&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Chuck Noland&#x27;]&#125;]-&gt;(CastAway),</span><br><span class="line">      (HelenH)-[:ACTED_IN &#123;roles:[&#x27;Kelly Frears&#x27;]&#125;]-&gt;(CastAway),</span><br><span class="line">      (RobertZ)-[:DIRECTED]-&gt;(CastAway)</span><br><span class="line"></span><br><span class="line">      CREATE (OneFlewOvertheCuckoosNest:Movie &#123;title:&quot;One Flew Over the Cuckoo&#x27;s Nest&quot;, released:1975, tagline:&quot;If he&#x27;s crazy, what does that make you?&quot;&#125;)</span><br><span class="line">      CREATE (MilosF:Person &#123;name:&#x27;Milos Forman&#x27;, born:1932&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (JackN)-[:ACTED_IN &#123;roles:[&#x27;Randle McMurphy&#x27;]&#125;]-&gt;(OneFlewOvertheCuckoosNest),</span><br><span class="line">      (DannyD)-[:ACTED_IN &#123;roles:[&#x27;Martini&#x27;]&#125;]-&gt;(OneFlewOvertheCuckoosNest),</span><br><span class="line">      (MilosF)-[:DIRECTED]-&gt;(OneFlewOvertheCuckoosNest)</span><br><span class="line"></span><br><span class="line">      CREATE (SomethingsGottaGive:Movie &#123;title:&quot;Something&#x27;s Gotta Give&quot;, released:2003&#125;)</span><br><span class="line">      CREATE (DianeK:Person &#123;name:&#x27;Diane Keaton&#x27;, born:1946&#125;)</span><br><span class="line">      CREATE (NancyM:Person &#123;name:&#x27;Nancy Meyers&#x27;, born:1949&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (JackN)-[:ACTED_IN &#123;roles:[&#x27;Harry Sanborn&#x27;]&#125;]-&gt;(SomethingsGottaGive),</span><br><span class="line">      (DianeK)-[:ACTED_IN &#123;roles:[&#x27;Erica Barry&#x27;]&#125;]-&gt;(SomethingsGottaGive),</span><br><span class="line">      (Keanu)-[:ACTED_IN &#123;roles:[&#x27;Julian Mercer&#x27;]&#125;]-&gt;(SomethingsGottaGive),</span><br><span class="line">      (NancyM)-[:DIRECTED]-&gt;(SomethingsGottaGive),</span><br><span class="line">      (NancyM)-[:PRODUCED]-&gt;(SomethingsGottaGive),</span><br><span class="line">      (NancyM)-[:WROTE]-&gt;(SomethingsGottaGive)</span><br><span class="line"></span><br><span class="line">      CREATE (BicentennialMan:Movie &#123;title:&#x27;Bicentennial Man&#x27;, released:1999, tagline:&quot;One robot&#x27;s 200 year journey to become an ordinary man.&quot;&#125;)</span><br><span class="line">      CREATE (ChrisC:Person &#123;name:&#x27;Chris Columbus&#x27;, born:1958&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (Robin)-[:ACTED_IN &#123;roles:[&#x27;Andrew Marin&#x27;]&#125;]-&gt;(BicentennialMan),</span><br><span class="line">      (OliverP)-[:ACTED_IN &#123;roles:[&#x27;Rupert Burns&#x27;]&#125;]-&gt;(BicentennialMan),</span><br><span class="line">      (ChrisC)-[:DIRECTED]-&gt;(BicentennialMan)</span><br><span class="line"></span><br><span class="line">      CREATE (CharlieWilsonsWar:Movie &#123;title:&quot;Charlie Wilson&#x27;s War&quot;, released:2007, tagline:&quot;A stiff drink. A little mascara. A lot of nerve. Who said they couldn&#x27;t bring down the Soviet empire.&quot;&#125;)</span><br><span class="line">      CREATE (JuliaR:Person &#123;name:&#x27;Julia Roberts&#x27;, born:1967&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Rep. Charlie Wilson&#x27;]&#125;]-&gt;(CharlieWilsonsWar),</span><br><span class="line">      (JuliaR)-[:ACTED_IN &#123;roles:[&#x27;Joanne Herring&#x27;]&#125;]-&gt;(CharlieWilsonsWar),</span><br><span class="line">      (PhilipH)-[:ACTED_IN &#123;roles:[&#x27;Gust Avrakotos&#x27;]&#125;]-&gt;(CharlieWilsonsWar),</span><br><span class="line">      (MikeN)-[:DIRECTED]-&gt;(CharlieWilsonsWar)</span><br><span class="line"></span><br><span class="line">      CREATE (ThePolarExpress:Movie &#123;title:&#x27;The Polar Express&#x27;, released:2004, tagline:&#x27;This Holiday Season... Believe&#x27;&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Hero Boy&#x27;, &#x27;Father&#x27;, &#x27;Conductor&#x27;, &#x27;Hobo&#x27;, &#x27;Scrooge&#x27;, &#x27;Santa Claus&#x27;]&#125;]-&gt;(ThePolarExpress),</span><br><span class="line">      (RobertZ)-[:DIRECTED]-&gt;(ThePolarExpress)</span><br><span class="line"></span><br><span class="line">      CREATE (ALeagueofTheirOwn:Movie &#123;title:&#x27;A League of Their Own&#x27;, released:1992, tagline:&#x27;Once in a lifetime you get a chance to do something different.&#x27;&#125;)</span><br><span class="line">      CREATE (Madonna:Person &#123;name:&#x27;Madonna&#x27;, born:1954&#125;)</span><br><span class="line">      CREATE (GeenaD:Person &#123;name:&#x27;Geena Davis&#x27;, born:1956&#125;)</span><br><span class="line">      CREATE (LoriP:Person &#123;name:&#x27;Lori Petty&#x27;, born:1963&#125;)</span><br><span class="line">      CREATE (PennyM:Person &#123;name:&#x27;Penny Marshall&#x27;, born:1943&#125;)</span><br><span class="line">      CREATE</span><br><span class="line">      (TomH)-[:ACTED_IN &#123;roles:[&#x27;Jimmy Dugan&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (GeenaD)-[:ACTED_IN &#123;roles:[&#x27;Dottie Hinson&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (LoriP)-[:ACTED_IN &#123;roles:[&#x27;Kit Keller&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (RosieO)-[:ACTED_IN &#123;roles:[&#x27;Doris Murphy&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (Madonna)-[:ACTED_IN &#123;roles:[&#x27;&quot;All the Way&quot; Mae Mordabito&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (BillPax)-[:ACTED_IN &#123;roles:[&#x27;Bob Hinson&#x27;]&#125;]-&gt;(ALeagueofTheirOwn),</span><br><span class="line">      (PennyM)-[:DIRECTED]-&gt;(ALeagueofTheirOwn)</span><br><span class="line"></span><br><span class="line">      CREATE (PaulBlythe:Person &#123;name:&#x27;Paul Blythe&#x27;&#125;)</span><br><span class="line">      CREATE (AngelaScope:Person &#123;name:&#x27;Angela Scope&#x27;&#125;)</span><br><span class="line">      CREATE (JessicaThompson:Person &#123;name:&#x27;Jessica Thompson&#x27;&#125;)</span><br><span class="line">      CREATE (JamesThompson:Person &#123;name:&#x27;James Thompson&#x27;&#125;)</span><br><span class="line"></span><br><span class="line">      CREATE</span><br><span class="line">      (JamesThompson)-[:FOLLOWS]-&gt;(JessicaThompson),</span><br><span class="line">      (AngelaScope)-[:FOLLOWS]-&gt;(JessicaThompson),</span><br><span class="line">      (PaulBlythe)-[:FOLLOWS]-&gt;(AngelaScope)</span><br><span class="line"></span><br><span class="line">      CREATE</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&#x27;An amazing journey&#x27;, rating:95&#125;]-&gt;(CloudAtlas),</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&#x27;Silly, but fun&#x27;, rating:65&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (JamesThompson)-[:REVIEWED &#123;summary:&#x27;The coolest football movie ever&#x27;, rating:100&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (AngelaScope)-[:REVIEWED &#123;summary:&#x27;Pretty funny at times&#x27;, rating:62&#125;]-&gt;(TheReplacements),</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&#x27;Dark, but compelling&#x27;, rating:85&#125;]-&gt;(Unforgiven),</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&quot;Slapstick redeemed only by the Robin Williams and Gene Hackman&#x27;s stellar performances&quot;, rating:45&#125;]-&gt;(TheBirdcage),</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&#x27;A solid romp&#x27;, rating:68&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (JamesThompson)-[:REVIEWED &#123;summary:&#x27;Fun, but a little far fetched&#x27;, rating:65&#125;]-&gt;(TheDaVinciCode),</span><br><span class="line">      (JessicaThompson)-[:REVIEWED &#123;summary:&#x27;You had me at Jerry&#x27;, rating:92&#125;]-&gt;(JerryMaguire)</span><br><span class="line"></span><br><span class="line">      WITH TomH as a</span><br><span class="line">      MATCH (a)-[:ACTED_IN]-&gt;(m)&lt;-[:DIRECTED]-(d) RETURN a,m,d LIMIT 10;</span><br></pre></td></tr></table></figure>


<h2 id="Create-constraints"><a href="#Create-constraints" class="headerlink" title="Create constraints"></a>Create constraints</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE CONSTRAINT ON (n:Movie) ASSERT (n.title) IS UNIQUE</span><br></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE CONSTRAINT ON (n:Person) ASSERT (n.name) IS UNIQUE</span><br></pre></td></tr></table></figure>

<h2 id="Index-nodes"><a href="#Index-nodes" class="headerlink" title="Index nodes"></a>Index nodes</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE INDEX FOR (m:Movie) ON (m.released)</span><br></pre></td></tr></table></figure>



<h2 id="Find"><a href="#Find" class="headerlink" title="Find"></a>Find</h2><p>Find the actor named “Tom Hanks”:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MATCH (tom:Person &#123;name: &quot;Tom Hanks&quot;&#125;) RETURN tom</span><br></pre></td></tr></table></figure>



<p>Find the movie with title “Cloud Atlas”:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MATCH (cloudAtlas:Movie &#123;title: &quot;Cloud Atlas&quot;&#125;) RETURN cloudAtlas</span><br></pre></td></tr></table></figure>



<p>Find 10 people and return their names:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MATCH (people:Person) RETURN people.name LIMIT 10</span><br></pre></td></tr></table></figure>



<p>result</p>
<table>
<thead>
<tr>
<th>people.name</th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>“Keanu Reeves”</td>
</tr>
<tr>
<td>2</td>
<td>“Carrie-Anne Moss”</td>
</tr>
<tr>
<td>3</td>
<td>“Laurence Fishburne”</td>
</tr>
<tr>
<td>4</td>
<td>“Hugo Weaving”</td>
</tr>
<tr>
<td>5</td>
<td>“Lilly Wachowski”</td>
</tr>
<tr>
<td>6</td>
<td>“Lana Wachowski”</td>
</tr>
<tr>
<td>7</td>
<td>“Joel Silver”</td>
</tr>
<tr>
<td>8</td>
<td>“Emil Eifrem”</td>
</tr>
<tr>
<td>9</td>
<td>“Charlize Theron”</td>
</tr>
<tr>
<td>10</td>
<td>“Al Pacino”</td>
</tr>
</tbody></table>
<p>Find movies released in the 1990s and return their titles.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MATCH (nineties:Movie) WHERE nineties.released &gt;= 1990 AND nineties.released &lt; 2000 RETURN nineties.title</span><br></pre></td></tr></table></figure>

<p>result</p>
<table>
<thead>
<tr>
<th>nineties.title</th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>“Joe Versus the Volcano”</td>
</tr>
<tr>
<td>2</td>
<td>“A Few Good Men”</td>
</tr>
<tr>
<td>3</td>
<td>“Unforgiven”</td>
</tr>
<tr>
<td>4</td>
<td>“Hoffa”</td>
</tr>
<tr>
<td>5</td>
<td>“A League of Their Own”</td>
</tr>
<tr>
<td>6</td>
<td>“Sleepless in Seattle”</td>
</tr>
<tr>
<td>7</td>
<td>“Johnny Mnemonic”</td>
</tr>
<tr>
<td>8</td>
<td>“Apollo 13”</td>
</tr>
<tr>
<td>9</td>
<td>“That Thing You Do”</td>
</tr>
<tr>
<td>10</td>
<td>“The Birdcage”</td>
</tr>
<tr>
<td>11</td>
<td>“Twister”</td>
</tr>
<tr>
<td>12</td>
<td>“The Devil’s Advocate”</td>
</tr>
<tr>
<td>13</td>
<td>“As Good as It Gets”</td>
</tr>
<tr>
<td>14</td>
<td>“What Dreams May Come”</td>
</tr>
<tr>
<td>15</td>
<td>“You’ve Got Mail”</td>
</tr>
<tr>
<td>16</td>
<td>“When Harry Met Sally”</td>
</tr>
<tr>
<td>17</td>
<td>“The Matrix”</td>
</tr>
<tr>
<td>18</td>
<td>“Snow Falling on Cedars”</td>
</tr>
<tr>
<td>19</td>
<td>“The Green Mile”</td>
</tr>
<tr>
<td>20</td>
<td>“Bicentennial Man”</td>
</tr>
</tbody></table>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/30/Nachos-VM/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/30/Nachos-VM/" class="post-title-link" itemprop="url">Nachos-VM</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-30 03:11:03 / 修改时间：03:16:38" itemprop="dateCreated datePublished" datetime="2021-12-30T03:11:03+08:00">2021-12-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/" itemprop="url" rel="index"><span itemprop="name">操作系统</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/28/%E6%96%87%E4%BB%B6%E5%88%86%E7%89%87%E4%B8%8E%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/28/%E6%96%87%E4%BB%B6%E5%88%86%E7%89%87%E4%B8%8E%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0/" class="post-title-link" itemprop="url">文件分片与断点续传</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-28 00:04:18 / 修改时间：01:54:31" itemprop="dateCreated datePublished" datetime="2021-12-28T00:04:18+08:00">2021-12-28</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="断点续传"><a href="#断点续传" class="headerlink" title="断点续传"></a>断点续传</h1><p>基于http协议实现断点续传。</p>
<p>请求部分，需要在请求头里加入Range头，表示本次请求的byte数组的开始和结束位置。</p>
<p>格式为：Bytes&#x3D;开始-结束。如果不填表示0或者最后。</p>
<blockquote>
<p>对于要支持断点续传的服务器，需要处理这个请求头，如果发现有Range头部，需要对响应特殊处理。</p>
</blockquote>
<ul>
<li><p>code：返回206；</p>
</li>
<li><p>header：需要返回如下几个header：</p>
<ul>
<li>Content-Range: 格式为bytes 开始-结束&#x2F;全部，如 bytes 0-10&#x2F;3103</li>
<li>Content-Type，对于二进制数据是application&#x2F;octet-stream</li>
<li>Content-Length: 如1024，本次内容的大小</li>
<li>Accept-Ranges：bytes，表示支持Range请求</li>
</ul>
</li>
<li><p>body：返回Range范围内的字节；</p>
</li>
</ul>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/u011748319/article/details/118680680">https://blog.csdn.net/u011748319/article/details/118680680</a></p>
<p><a target="_blank" rel="noopener" href="https://www.iteye.com/blog/rensanning-2248760">https://www.iteye.com/blog/rensanning-2248760</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_29009501/article/details/114543338?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.highlightwordscore&spm=1001.2101.3001.4242.1">https://blog.csdn.net/weixin_29009501/article/details/114543338?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.highlightwordscore&amp;spm=1001.2101.3001.4242.1</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/27/CORS/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/27/CORS/" class="post-title-link" itemprop="url">CORS</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-27 23:43:21 / 修改时间：23:43:47" itemprop="dateCreated datePublished" datetime="2021-12-27T23:43:21+08:00">2021-12-27</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p><a target="_blank" rel="noopener" href="https://www.ruanyifeng.com/blog/2016/04/cors.html">https://www.ruanyifeng.com/blog/2016/04/cors.html</a></p>
<p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS">https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/27/JWT/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/27/JWT/" class="post-title-link" itemprop="url">JWT</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-27 14:35:45 / 修改时间：23:59:33" itemprop="dateCreated datePublished" datetime="2021-12-27T14:35:45+08:00">2021-12-27</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <blockquote>
<p>在一个web项目中总需要考虑的一个问题就是如何认证用户的身份。</p>
</blockquote>
<h1 id="用户的认证方式"><a href="#用户的认证方式" class="headerlink" title="用户的认证方式"></a>用户的认证方式</h1><h2 id="传统的session认证"><a href="#传统的session认证" class="headerlink" title="传统的session认证"></a>传统的session认证</h2><p>互联网服务离不开用户认证。一般流程是下面这样。</p>
<blockquote>
<p>1、用户向服务器发送用户名和密码。</p>
<p>2、服务器验证通过后，在当前对话（session）里面保存相关数据，比如用户角色、登录时间等等。</p>
<p>3、服务器向用户返回一个 session_id，写入用户的 Cookie。</p>
<p>4、用户随后的每一次请求，都会通过 Cookie，将 session_id 传回服务器。</p>
<p>5、服务器收到 session_id，找到前期保存的数据，由此得知用户的身份。</p>
</blockquote>
<p>我们知道，http协议本身是一种无状态的协议，而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证，那么下一次请求时，用户还要再一次进行用户认证才行。</p>
<p>因为根据http协议，我们并不能知道是哪个用户发出的请求，所以<strong>为了让我们的应用能识别是哪个用户发出的请求</strong>，我们只能<strong>在服务器存储一份用户登录的信息</strong>，这份登录信息会在响应时传递给浏览器，<strong>将SessionID告诉客户端保存在cookie中，以便下次请求时发送给我们的应用</strong>，这样我们的应用就能识别请求来自哪个用户了，这就是传统的基于session认证。</p>
<p>但是这种基于session的认证使应用本身很难得到扩展，随着不同客户端用户的增加，独立的服务器已无法承载更多的用户，而这时候基于session认证应用的问题就会暴露出来。</p>
<h3 id="基于session认证所显露的问题"><a href="#基于session认证所显露的问题" class="headerlink" title="基于session认证所显露的问题"></a>基于session认证所显露的问题</h3><ul>
<li>Session: 每个用户经过我们的应用认证之后，我们的应用都要在服务端做一次记录，以方便用户下次请求的鉴别，通常而言session都是保存在内存中，而随着认证用户的增多，服务端的开销会明显增大。</li>
<li>水平扩展困难: 用户认证之后，服务端做认证记录，如果认证的记录被保存在内存中的话，这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源，这样在分布式的应用上，相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。</li>
<li>CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获，用户就会很容易受到跨站请求伪造的攻击。</li>
</ul>
<blockquote>
<p><a target="_blank" rel="noopener" href="https://tech.meituan.com/2018/10/11/fe-security-csrf.html">前端安全系列（二）：如何防止CSRF攻击？</a></p>
</blockquote>
<h2 id="基于token的鉴权机制"><a href="#基于token的鉴权机制" class="headerlink" title="基于token的鉴权机制"></a>基于token的鉴权机制</h2><p>基于token的鉴权机制类似于http协议也是无状态的，它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了，这就为应用的扩展提供了便利。</p>
<p>流程：</p>
<ol>
<li>用户使用账户、密码来请求服务器</li>
<li>服务器进行验证用户的信息</li>
<li>服务器通过验证发送给用户一个token</li>
<li>客户端存储token，并在每次请求时附送上这个token值</li>
<li>服务端验证token值，并返回数据</li>
</ol>
<h1 id="JWT"><a href="#JWT" class="headerlink" title="JWT"></a>JWT</h1><h2 id="什么是JWT及原理"><a href="#什么是JWT及原理" class="headerlink" title="什么是JWT及原理"></a>什么是JWT及原理</h2><p>JWT(JSON Web Token) 是一个开放标准(RFC 7519)，它定义了一种<strong>紧凑的</strong>、<strong>自包含的</strong>（内部包含了一些会话信息）方式，</p>
<p><strong>用于作为JSON对象在各方之间安全地传输信息****。该信息可以被验证和信任</strong>，因为它是有数字签名的。</p>
<p>JWT 的原理是，服务器认证以后，生成一个 JSON 对象，发回给用户，就像下面这样。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;姓名&quot;</span><span class="punctuation">:</span> <span class="string">&quot;张三&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;角色&quot;</span><span class="punctuation">:</span> <span class="string">&quot;管理员&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;到期时间&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2018年7月1日0点0分&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>



<p>以后，用户与服务端通信的时候，都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据，服务器在生成这个对象的时候，会加上签名（详见后文）。</p>
<p>服务器就不保存任何 session 数据了，也就是说，服务器变成无状态了，从而比较容易实现扩展。</p>
<h2 id="JWT的构成"><a href="#JWT的构成" class="headerlink" title="JWT的构成"></a>JWT的构成</h2><p>JWT由三部分组成，它们之间用圆点(.)连接。这三部分分别是：</p>
<ul>
<li>Header</li>
<li>Payload</li>
<li>Signature</li>
</ul>
<p>三种都是经过Base64URL编码后的串。</p>
<p>写成一行，就是下面的样子。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Header</span>.<span class="property">Payload</span>.<span class="property">Signature</span></span><br></pre></td></tr></table></figure>



<p>具体的构成方式如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">base64(header).base64(payload).base64( HS256(base64(header) + &quot;.&quot; + base64(payload), secret) )</span><br></pre></td></tr></table></figure>



<h3 id="Header"><a href="#Header" class="headerlink" title="Header"></a>Header</h3><p>jwt的头部由两部分信息组成：</p>
<ul>
<li>type：声明类型，这里是jwt</li>
<li>alg：声明加密的算法 通常直接使用 HMAC SHA256</li>
</ul>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;typ&quot;</span><span class="punctuation">:</span><span class="string">&quot;jwt&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;alg&quot;</span><span class="punctuation">:</span><span class="string">&quot;HS256&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>对头部信息进行Base64编码的得到第一部分的信息。</p>
<h3 id="Payload"><a href="#Payload" class="headerlink" title="Payload"></a>Payload</h3><p>载荷就是存放有效信息的地方,它包含声明（要求）。声明有三种类型：</p>
<ul>
<li>registered claims：标准中注册的声明。这里有一组预定义的声明，它们不是强制的，但是推荐</li>
<li>public claims：公共的声明</li>
<li>private claims：私有的声明</li>
</ul>
<p><strong>标准中注册的声明 (建议但不强制使用) ：</strong></p>
<ul>
<li>iss: jwt签发者</li>
<li>sub: jwt所面向的用户</li>
<li>aud: 接收jwt的一方</li>
<li>exp: jwt的过期时间，这个过期时间必须要大于签发时间</li>
<li>nbf: 定义在什么时间之前，该jwt都是不可用的</li>
<li>iat: jwt的签发时间</li>
<li>jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击</li>
</ul>
<p><strong>公共的声明 ：</strong></p>
<p>公共的声明可以添加任何的信息，一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息，因为该部分在客户端可解密.</p>
<p><strong>私有的声明 ：</strong></p>
<p>私有声明是提供者和消费者所共同定义的声明，一般不建议存放敏感信息，因为base64是对称解密的，意味着该部分信息可以归类为明文信息。</p>
<p>对Payload进行Base64加密就得到了JWT第二部分的内容。</p>
<h3 id="Signature"><a href="#Signature" class="headerlink" title="Signature"></a>Signature</h3><p>JWT的第三部分是一个签证信息，这个签证信息由三部分组成：</p>
<ul>
<li>header (base64后的)</li>
<li>payload (base64后的)</li>
<li>secret</li>
</ul>
<p><strong>Signature 部分是对前两部分的签名，防止数据篡改。</strong></p>
<p>第三部分需要base64加密后的header和base64加密后的payload使用 <code>.</code> 连接组成的字符串，然后通过header中声明的加密方式进行加盐secret组合加密，然后就构成了JWT的第三部分。</p>
<p><strong>注意：</strong><br> secret是保存在服务器端的，JWT的签发生成也是在服务器端的，<strong>secret就是用来进行JWT的签发和JWT的验证，所以，它就是你服务端的私钥，在任何场景都不应该流露出去</strong>。</p>
<p>一旦客户端得知这个secret, 那就意味着客户端是可以自我签发JWT了。</p>
<h2 id="JWT的几个特点"><a href="#JWT的几个特点" class="headerlink" title="JWT的几个特点"></a>JWT的几个特点</h2><p>（1）JWT 默认是不加密，但也是可以加密的。生成原始 Token 以后，可以用密钥再加密一次。（？？？）</p>
<p>（2）JWT 不加密的情况下，不能将秘密数据写入 JWT。</p>
<p>（3）JWT 不仅可以用于认证，也可以用于交换信息。有效使用 JWT，可以降低服务器查询数据库的次数。</p>
<p>（4）JWT 的最大缺点是，由于服务器不保存 session 状态，因此无法在使用过程中废止某个 token，或者更改 token 的权限。也就是说，一旦 JWT 签发了，在到期之前就会始终有效，除非服务器部署额外的逻辑。</p>
<p>（5）JWT 本身包含了认证信息，一旦泄露，任何人都可以获得该令牌的所有权限。为了减少盗用，JWT 的有效期应该设置得比较短。对于一些比较重要的权限，使用时应该再次对用户进行认证。</p>
<p>（6）为了减少盗用，JWT 不应该使用 HTTP 协议明码传输，要使用 HTTPS 协议传输。</p>
<h2 id="基于jjwt使用JWT"><a href="#基于jjwt使用JWT" class="headerlink" title="基于jjwt使用JWT"></a>基于jjwt使用JWT</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">LearnJwtApplicationTests</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">secret</span> <span class="operator">=</span> <span class="string">&quot;secret&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String secretBase64;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        secretBase64 = Base64.getEncoder().encodeToString(secret.getBytes());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">testJwtCreate</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">JwtBuilder</span> <span class="variable">jwtBuilder</span> <span class="operator">=</span> Jwts.builder();</span><br><span class="line">        <span class="type">String</span> <span class="variable">token</span> <span class="operator">=</span> jwtBuilder</span><br><span class="line">                <span class="comment">// header</span></span><br><span class="line">                .setHeaderParam(<span class="string">&quot;alg&quot;</span>, <span class="string">&quot;HS256&quot;</span>)</span><br><span class="line">                .setHeaderParam(<span class="string">&quot;typ&quot;</span>, <span class="string">&quot;JWT&quot;</span>)</span><br><span class="line">                <span class="comment">// payload</span></span><br><span class="line">                .claim(<span class="string">&quot;sub&quot;</span>, <span class="string">&quot;1234567890&quot;</span>) <span class="comment">// 标准声明</span></span><br><span class="line">                .claim(<span class="string">&quot;iat&quot;</span>, <span class="number">1516239022</span>)   <span class="comment">// 标准声明</span></span><br><span class="line">                .claim(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;John Doe&quot;</span>)  <span class="comment">// 自定义声明</span></span><br><span class="line">                <span class="comment">// signature</span></span><br><span class="line">                .signWith(SignatureAlgorithm.HS256, secretBase64)</span><br><span class="line">                .compact();</span><br><span class="line"></span><br><span class="line">        System.out.println();</span><br><span class="line">        System.out.println(token);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">testJWTParse</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">token</span> <span class="operator">=</span> <span class="string">&quot;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.&quot;</span> +</span><br><span class="line"><span class="comment">//                &quot;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.&quot;+</span></span><br><span class="line">                <span class="string">&quot;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9vIiwiaWF0IjoxNTE2MjM5MDIyfQ.&quot;</span> +</span><br><span class="line">                <span class="string">&quot;XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o&quot;</span>;</span><br><span class="line">        <span class="type">JwtParser</span> <span class="variable">jwtParser</span> <span class="operator">=</span> Jwts.parser();</span><br><span class="line">        Jws&lt;Claims&gt; claimsJws = jwtParser.setSigningKey(secretBase64).parseClaimsJws(token);</span><br><span class="line">        <span class="type">JwsHeader</span> <span class="variable">header</span> <span class="operator">=</span> claimsJws.getHeader();</span><br><span class="line">        <span class="type">Claims</span> <span class="variable">body</span> <span class="operator">=</span> claimsJws.getBody();</span><br><span class="line">        <span class="type">String</span> <span class="variable">signature</span> <span class="operator">=</span> claimsJws.getSignature();</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;----- header -----&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;alg : &quot;</span> + header.getAlgorithm());</span><br><span class="line">        System.out.println(<span class="string">&quot;typ : &quot;</span>+header.getType());</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;----- body -----&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;sub : &quot;</span>+body.getSubject());</span><br><span class="line">        System.out.println(<span class="string">&quot;iat : &quot;</span>+body.getIssuedAt());</span><br><span class="line">        System.out.println(<span class="string">&quot;name : &quot;</span>+body.get(<span class="string">&quot;name&quot;</span>));</span><br><span class="line">        System.out.println(<span class="string">&quot;id : &quot;</span>+body.getId());</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;----- signature -----&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;signature : &quot;</span> + signature);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>






<h1 id="JWT的使用方式"><a href="#JWT的使用方式" class="headerlink" title="JWT的使用方式"></a>JWT的使用方式</h1><h2 id="前端"><a href="#前端" class="headerlink" title="前端"></a>前端</h2><h3 id="前端储存JWT"><a href="#前端储存JWT" class="headerlink" title="前端储存JWT"></a>前端储存JWT</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&#x27;axios&#x27;</span>;</span><br><span class="line">axios.<span class="title function_">post</span>(</span><br><span class="line">	<span class="string">&quot;/user/login&quot;</span>,</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="attr">username</span>: <span class="variable language_">this</span>.<span class="property">userId</span>,</span><br><span class="line">		<span class="attr">password</span>: <span class="variable language_">this</span>.<span class="property">userPsw</span>,</span><br><span class="line">	&#125;,</span><br><span class="line">).<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>)=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (res.<span class="property">status</span> === <span class="number">200</span>) &#123;</span><br><span class="line">		<span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">&quot;token&quot;</span>, res.<span class="property">data</span>.<span class="property">data</span>);</span><br><span class="line">		<span class="variable language_">this</span>.$message(&#123;</span><br><span class="line">			<span class="attr">title</span>: <span class="string">&quot;登录成功&quot;</span>,</span><br><span class="line">			<span class="attr">message</span>: <span class="string">&quot;登录成功！正在为您跳转页面...&quot;</span>,</span><br><span class="line">			<span class="attr">type</span>: <span class="string">&quot;success&quot;</span>,</span><br><span class="line">			<span class="attr">duration</span>: <span class="number">1000</span>,</span><br><span class="line">			<span class="attr">showClose</span>: <span class="literal">false</span>,</span><br><span class="line">			<span class="attr">onClose</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">				<span class="variable language_">this</span>.<span class="property">$store</span>.<span class="title function_">dispatch</span>(<span class="string">&quot;setNoToken&quot;</span>, <span class="literal">false</span>);</span><br><span class="line">				<span class="variable language_">this</span>.<span class="property">$router</span>.<span class="title function_">go</span>(-<span class="number">1</span>);</span><br><span class="line">			&#125;,</span><br><span class="line">		&#125;);</span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="variable language_">this</span>.$alert(</span><br><span class="line">			<span class="string">`错误代码<span class="subst">$&#123;res.data.code&#125;</span>：<span class="subst">$&#123;res.data.message&#125;</span>`</span>,</span><br><span class="line">			<span class="string">&quot;登录失败&quot;</span>,</span><br><span class="line">			&#123;</span><br><span class="line">				<span class="attr">type</span>: <span class="string">&quot;error&quot;</span>,</span><br><span class="line">			&#125;</span><br><span class="line">		);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>





<h3 id="请求携带JWT"><a href="#请求携带JWT" class="headerlink" title="请求携带JWT"></a>请求携带JWT</h3><p>客户端收到服务器返回的 JWT，可以储存在 Cookie 里面，也可以储存在 localStorage。</p>
<p>此后，客户端每次与服务器通信，都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送，但是这样不能跨域(<a target="_blank" rel="noopener" href="https://www.cnblogs.com/imgss/p/cors.html">cookie跨域那些事</a>)，所以更好的做法是放在 HTTP 请求的头信息<code>Authorization</code>字段里面。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Authorization</span>: <span class="title class_">Bearer</span> &lt;token&gt;</span><br></pre></td></tr></table></figure>

<p>另一种做法是，跨域的时候，JWT 就放在 POST 请求的数据体里面。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&#x27;axios&#x27;</span>;</span><br><span class="line">axios.<span class="title function_">post</span>(</span><br><span class="line">	<span class="string">&#x27;/test&#x27;</span>, <span class="comment">// url</span></span><br><span class="line">	&#123;<span class="attr">num</span>: <span class="number">1</span>&#125;, <span class="comment">// data</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="attr">headers</span>: &#123;</span><br><span class="line">			<span class="title class_">Authorization</span>: <span class="string">`Bearer <span class="subst">$&#123;token&#125;</span>`</span></span><br><span class="line">		&#125;</span><br><span class="line">	&#125;, <span class="comment">// options</span></span><br><span class="line">).<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>)=&gt;</span>&#123;</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(res);</span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<img src="JWT/jwt1.png" style="zoom:60%;" />





<h3 id="前端提取JWT携带的信息"><a href="#前端提取JWT携带的信息" class="headerlink" title="前端提取JWT携带的信息"></a>前端提取JWT携带的信息</h3><p>前面也有提到，JWT的payload模块可以携带一些业务逻辑所必要的非敏感信息。因此，前端需要能够解析出JWT字符串。<br>举个例子，在sduoj中，需要判断用户的登录信息是否合法，其中一项评判标准就是JWT是否过期。在后端的服务器代码中存在这一部分逻辑，而在前端的代码中，也包含了这一段逻辑代码。<br>前端的代码逻辑中，仅在用户首次与sduoj的前端页面建立会话时进行判断。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 首先判断localStorage中是否存在token字段</span></span><br><span class="line"><span class="keyword">if</span>(<span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">&quot;token&quot;</span>) !== <span class="literal">null</span>) &#123;</span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * 注意，由于localStorage是以字符串形式取出的</span></span><br><span class="line"><span class="comment">	 * 当token字段是空字符串时，javascript会将其转换为布尔值false。</span></span><br><span class="line"><span class="comment">	 * 因此需要增加!==null进行判断。	</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	<span class="comment">// 使用模块加载器将通过yarn安装的jsonwebtoken加载进来</span></span><br><span class="line">	<span class="keyword">let</span> jwt = <span class="built_in">require</span>(<span class="string">&quot;jsonwebtoken&quot;</span>); </span><br><span class="line">	<span class="comment">// 使用jsonwebtoken解析JWT字符串</span></span><br><span class="line">	<span class="keyword">const</span> <span class="variable constant_">TOKEN</span> = jwt.<span class="title function_">decode</span>(<span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">&quot;token&quot;</span>));</span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * 通过jsonwebtoken解析后将会得到包含payload非敏感部分明文的JSON对象</span></span><br><span class="line"><span class="comment">	 * 提取jwt的过期时间，过期时间处在exp字段下</span></span><br><span class="line"><span class="comment">	 * 注意：jwt的时间单位比javascript、java等语言的时间单位要大3个数量级</span></span><br><span class="line"><span class="comment">	 * 因此，需要给解析出的时间乘上1000</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	<span class="keyword">let</span> exp = <span class="variable constant_">TOKEN</span>.<span class="property">exp</span> * <span class="number">1000</span>;</span><br><span class="line">	<span class="comment">// 判断当前时间是否已超过token的过期时间</span></span><br><span class="line">	<span class="keyword">if</span> (exp &lt;= <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">getTime</span>()) &#123;</span><br><span class="line">		<span class="variable language_">this</span>.$message(&#123;</span><br><span class="line">			<span class="attr">message</span>: <span class="string">&quot;您的身份认证已过期，请重新登陆&quot;</span>,</span><br><span class="line">			<span class="attr">type</span>: <span class="string">&quot;warning&quot;</span>,</span><br><span class="line">			<span class="attr">duration</span>: <span class="number">1000</span>,</span><br><span class="line">			<span class="attr">onClose</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">				<span class="comment">/**</span></span><br><span class="line"><span class="comment">				 * 消息提示关闭后执行两项任务</span></span><br><span class="line"><span class="comment">				 * 1.将过期的token字段从localStorage中移除</span></span><br><span class="line"><span class="comment">				 * 2.为用户跳转至登录界面</span></span><br><span class="line"><span class="comment">				 */</span></span><br><span class="line">				<span class="variable language_">localStorage</span>.<span class="title function_">removeItem</span>(<span class="string">&quot;token&quot;</span>);</span><br><span class="line">				<span class="variable language_">this</span>.<span class="property">$router</span>.<span class="title function_">push</span>(<span class="string">&quot;/login&quot;</span>);</span><br><span class="line">			&#125;,</span><br><span class="line">		&#125;);</span><br><span class="line">	&#125;</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">	<span class="comment">// 当localStorage中不存在token字段时，自动跳转至登录界面</span></span><br><span class="line">	<span class="variable language_">this</span>.<span class="property">$router</span>.<span class="title function_">push</span>(<span class="string">&quot;/login&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>




<h2 id="后端（SpringBoot）"><a href="#后端（SpringBoot）" class="headerlink" title="后端（SpringBoot）"></a>后端（SpringBoot）</h2><h3 id="生成、解析JWT"><a href="#生成、解析JWT" class="headerlink" title="生成、解析JWT"></a>生成、解析JWT</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.jsy.learnjwt.util;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.jsy.learnjwt.entity.CheckResult;</span><br><span class="line"><span class="keyword">import</span> com.jsy.learnjwt.entity.SystemConstant;</span><br><span class="line"><span class="keyword">import</span> io.jsonwebtoken.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.crypto.SecretKey;</span><br><span class="line"><span class="keyword">import</span> javax.crypto.spec.SecretKeySpec;</span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JwtUtil</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 签发JWT</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> id        JWT的唯一标识</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> subject   代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userId，roleId之类的，作为什么用户的唯一标志</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> ttlMillis 有效时间</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">createJWT</span><span class="params">(String id, String subject, Long ttlMillis)</span> &#123;</span><br><span class="line">        <span class="type">long</span> <span class="variable">nowMillis</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line">        <span class="type">Date</span> <span class="variable">now</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Date</span>(nowMillis);</span><br><span class="line">        <span class="type">SecretKey</span> <span class="variable">secretKey</span> <span class="operator">=</span> generalKey();</span><br><span class="line">        <span class="type">JwtBuilder</span> <span class="variable">builder</span> <span class="operator">=</span> Jwts.builder()</span><br><span class="line">                .setId(id) <span class="comment">// 是JWT的唯一标识，根据业务需要，这个可以设置为一个不重复的值，主要用来作为一次性token,从而回避重放攻击。</span></span><br><span class="line">                .setSubject(subject)</span><br><span class="line">                .setIssuer(<span class="string">&quot;user&quot;</span>)     <span class="comment">// 颁发者是使用 HTTP 或 HTTPS 方案的 URL（区分大小写），其中包含方案、主机及（可选的）端口号和路径部分</span></span><br><span class="line">                .setIssuedAt(now)      <span class="comment">// jwt的签发时间</span></span><br><span class="line">                .signWith(SignatureAlgorithm.HS256, secretKey); <span class="comment">// 设置签名使用的签名算法和签名使用的秘钥</span></span><br><span class="line">        <span class="keyword">if</span> (ttlMillis &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="type">long</span> <span class="variable">expMillis</span> <span class="operator">=</span> nowMillis + ttlMillis;</span><br><span class="line">            <span class="type">Date</span> <span class="variable">expDate</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Date</span>(expMillis);</span><br><span class="line">            builder.setExpiration(expDate); <span class="comment">// 过期时间</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> builder.compact();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 验证JWT</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> CheckResult <span class="title function_">validateJWT</span><span class="params">(String jwtStr)</span> &#123;</span><br><span class="line">        <span class="type">CheckResult</span> <span class="variable">checkResult</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">CheckResult</span>();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Claims</span> <span class="variable">claims</span> <span class="operator">=</span> parseJWT(jwtStr);</span><br><span class="line">            checkResult.setClaims(claims);</span><br><span class="line">            checkResult.setSuccess(<span class="literal">true</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ExpiredJwtException e) &#123;  <span class="comment">// JWT 过期</span></span><br><span class="line">            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE);</span><br><span class="line">            checkResult.setSuccess(<span class="literal">false</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);</span><br><span class="line">            checkResult.setSuccess(<span class="literal">false</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> checkResult;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> SecretKey <span class="title function_">generalKey</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">byte</span>[] encodedKey = SystemConstant.JWT_SECRET.getBytes();</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">SecretKeySpec</span>(encodedKey, <span class="number">0</span>, encodedKey.length, <span class="string">&quot;AES&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 解析JWT字符串</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Claims <span class="title function_">parseJWT</span><span class="params">(String jwt)</span> &#123;</span><br><span class="line">        <span class="type">SecretKey</span> <span class="variable">secretKey</span> <span class="operator">=</span> generalKey();</span><br><span class="line">        <span class="keyword">return</span> Jwts.parser()</span><br><span class="line">                .setSigningKey(secretKey)</span><br><span class="line">                .parseClaimsJws(jwt)</span><br><span class="line">                .getBody();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="拦截器处理token的验证"><a href="#拦截器处理token的验证" class="headerlink" title="拦截器处理token的验证"></a>拦截器处理token的验证</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.jsy.learnjwt.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.JSONObject;</span><br><span class="line"><span class="keyword">import</span> com.jsy.learnjwt.entity.CheckResult;</span><br><span class="line"><span class="keyword">import</span> com.jsy.learnjwt.entity.SystemConstant;</span><br><span class="line"><span class="keyword">import</span> com.jsy.learnjwt.util.JwtUtil;</span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.apache.commons.lang3.StringUtils;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.HandlerInterceptor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.Cookie;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.nio.charset.StandardCharsets;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: SongyangJi</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@since</span>: 2021/12/27</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyInterceptor</span> <span class="keyword">implements</span> <span class="title class_">HandlerInterceptor</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">preHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 1.从Cookie获取token</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">token</span> <span class="operator">=</span> getTokenFromCookie(request);</span><br><span class="line">        <span class="keyword">if</span> (StringUtils.isBlank(token)) &#123;</span><br><span class="line">            <span class="comment">// 2.从headers中获取</span></span><br><span class="line">            token = request.getHeader(<span class="string">&quot;token&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (StringUtils.isBlank(token)) &#123;</span><br><span class="line">            <span class="comment">// 3.从请求参数获取</span></span><br><span class="line">            token = request.getParameter(<span class="string">&quot;token&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (StringUtils.isBlank(token)) &#123;</span><br><span class="line">            <span class="comment">//输出响应流</span></span><br><span class="line">            <span class="type">JSONObject</span> <span class="variable">jsonObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>();</span><br><span class="line">            jsonObject.put(<span class="string">&quot;msg&quot;</span>, <span class="string">&quot;403&quot;</span>);</span><br><span class="line">            response.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">            response.setContentType(<span class="string">&quot;application/json; charset=utf-8&quot;</span>);</span><br><span class="line">            response.getOutputStream().write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 验证token</span></span><br><span class="line">        <span class="type">CheckResult</span> <span class="variable">checkResult</span> <span class="operator">=</span> JwtUtil.validateJWT(token);</span><br><span class="line">        <span class="keyword">if</span> (checkResult.isSuccess()) &#123;</span><br><span class="line">            <span class="comment">// 验证通过</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (checkResult.getErrCode().equals(SystemConstant.JWT_ERRCODE_EXPIRE)) &#123;</span><br><span class="line">                <span class="comment">//输出响应流</span></span><br><span class="line">                <span class="type">JSONObject</span> <span class="variable">jsonObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>();</span><br><span class="line">                jsonObject.put(<span class="string">&quot;msg&quot;</span>, SystemConstant.JWT_ERRCODE_EXPIRE);</span><br><span class="line">                response.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">                response.setContentType(<span class="string">&quot;application/json; charset=utf-8&quot;</span>);</span><br><span class="line">                response.getOutputStream().write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (checkResult.getErrCode().equals(SystemConstant.JWT_ERRCODE_FAIL)) &#123;</span><br><span class="line">                <span class="comment">//输出响应流</span></span><br><span class="line">                <span class="type">JSONObject</span> <span class="variable">jsonObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>();</span><br><span class="line">                jsonObject.put(<span class="string">&quot;msg&quot;</span>, SystemConstant.JWT_ERRCODE_FAIL);</span><br><span class="line">                response.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">                response.setContentType(<span class="string">&quot;application/json; charset=utf-8&quot;</span>);</span><br><span class="line">                response.getOutputStream().write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//输出响应流</span></span><br><span class="line">            <span class="type">JSONObject</span> <span class="variable">jsonObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>();</span><br><span class="line">            jsonObject.put(<span class="string">&quot;msg&quot;</span>, <span class="string">&quot;403&quot;</span>);</span><br><span class="line">            response.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">            response.setContentType(<span class="string">&quot;application/json; charset=utf-8&quot;</span>);</span><br><span class="line">            response.getOutputStream().write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String <span class="title function_">getTokenFromCookie</span><span class="params">(HttpServletRequest request)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">token</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        Cookie[] cookies = request.getCookies();</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="literal">null</span> == cookies ? <span class="number">0</span> : cookies.length;</span><br><span class="line">        <span class="keyword">if</span> (len &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">for</span> (Cookie cookie : cookies) &#123;</span><br><span class="line">                <span class="keyword">if</span> (cookie.getName().equals(<span class="string">&quot;token&quot;</span>)) &#123;</span><br><span class="line">                    token = cookie.getValue();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> token;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>设置对应路径的接口的拦截器</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WebMvcConfig</span> <span class="keyword">implements</span> <span class="title class_">WebMvcConfigurer</span> &#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> MyInterceptor myInterceptor;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addInterceptors</span><span class="params">(InterceptorRegistry registry)</span> &#123;</span><br><span class="line">        <span class="comment">// 设置对应路径的接口的拦截器</span></span><br><span class="line">        registry.addInterceptor(myInterceptor).addPathPatterns(<span class="string">&quot;/token/**&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a target="_blank" rel="noopener" href="https://jwt.io/">https://jwt.io/</a></p>
<p><a target="_blank" rel="noopener" href="https://jwt.io/introduction/">https://jwt.io/introduction/</a></p>
<p><a target="_blank" rel="noopener" href="http://www.jsons.cn/allencrypt/">http://www.jsons.cn/allencrypt/</a></p>
<p><a target="_blank" rel="noopener" href="https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html">https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_53126706/article/details/120925322?spm=1001.2014.3001.5501">https://blog.csdn.net/qq_53126706/article/details/120925322?spm=1001.2014.3001.5501</a></p>
<p><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/6623416161ff">https://www.jianshu.com/p/6623416161ff</a></p>
<p><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/4a124a10fcaf">https://www.jianshu.com/p/4a124a10fcaf</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/27/GoLang-00/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/27/GoLang-00/" class="post-title-link" itemprop="url">GoLang入门</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-12-27 00:28:14" itemprop="dateCreated datePublished" datetime="2021-12-27T00:28:14+08:00">2021-12-27</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-04 01:21:49" itemprop="dateModified" datetime="2022-12-04T01:21:49+08:00">2022-12-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Go/" itemprop="url" rel="index"><span itemprop="name">Go</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><p>pkg包安装简单，只需双击+一路next即可，安装路径默认是&#x2F;usr&#x2F;local&#x2F;go&#x2F;</p>
<p><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/Go">https://zh.wikipedia.org/wiki/Go</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/dl/">https://go.dev/dl/</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/">https://go.dev/</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/doc/install">https://go.dev/doc/install</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/doc/manage-install#installing-multiple">安装多个版本的go</a></p>
<h1 id="HelloWorld"><a href="#HelloWorld" class="headerlink" title="HelloWorld"></a>HelloWorld</h1><p>创建编辑文件<code>vim hello.go</code></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	fmt.Println(<span class="string">&quot;Hello World&quot;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>直接运行</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">jisongyang@SongyangJi-MacBookAir tmp % <span class="keyword">go</span> run hello.<span class="keyword">go</span></span><br><span class="line">Hello World</span><br></pre></td></tr></table></figure>



<p>先编译后执行（多一个编译产物）</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">jisongyang@SongyangJi-MacBookAir tmp % <span class="keyword">go</span> build -o hello hello.<span class="keyword">go</span></span><br><span class="line">jisongyang@SongyangJi-MacBookAir tmp % ls</span><br><span class="line">hello		hello.<span class="keyword">go</span></span><br><span class="line">jisongyang@SongyangJi-MacBookAir tmp % ./hello</span><br><span class="line">Hello World</span><br></pre></td></tr></table></figure>




      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/26/Java%E4%BD%BF%E7%94%A8jsch%E8%BF%9E%E6%8E%A5FTP%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%93%8D%E4%BD%9C%E6%96%87%E4%BB%B6/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/26/Java%E4%BD%BF%E7%94%A8jsch%E8%BF%9E%E6%8E%A5FTP%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%93%8D%E4%BD%9C%E6%96%87%E4%BB%B6/" class="post-title-link" itemprop="url">Java使用jsch连接FTP服务器操作文件</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-26 23:27:21 / 修改时间：23:27:33" itemprop="dateCreated datePublished" datetime="2021-12-26T23:27:21+08:00">2021-12-26</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <blockquote>
<p>本文主要在sdu-pta项目中如何使用 jsch 去连接 FTP服务器，并访问、下载、上传文件。</p>
</blockquote>
<h1 id="Maven依赖"><a href="#Maven依赖" class="headerlink" title="Maven依赖"></a>Maven依赖</h1><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.jcraft<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jsch<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>0.1.55<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>


<h1 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取Channel</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> ChannelSftp <span class="title function_">getSftp</span><span class="params">()</span> <span class="keyword">throws</span> SftpException &#123;</span><br><span class="line">    Session session;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        session = <span class="keyword">new</span> <span class="title class_">JSch</span>().getSession(sshProperties.getUsername(), sshProperties.getHost(), sshProperties.getPort());</span><br><span class="line">        session.setConfig(<span class="string">&quot;StrictHostKeyChecking&quot;</span>, <span class="string">&quot;no&quot;</span>);</span><br><span class="line">        session.setPassword(sshProperties.getPassword());</span><br><span class="line">        session.connect();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">        log.error(<span class="string">&quot;ssh connecting &quot;</span> + sshProperties.getUsername() + <span class="string">&quot;@&quot;</span> + sshProperties.getHost() + <span class="string">&quot; failed.&quot;</span>, e);</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    ChannelSftp sftp;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        sftp = (ChannelSftp) session.openChannel(<span class="string">&quot;sftp&quot;</span>);</span><br><span class="line">        sftp.connect();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">        log.error(<span class="string">&quot;channel opens fail&quot;</span>, e);</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sftp;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用配置类获取操作句柄</span></span><br><span class="line"><span class="type">ChannelSftp</span> <span class="variable">sftp</span> <span class="operator">=</span> sshConfiguration.getSftp();</span><br><span class="line"><span class="comment">// 使用后关闭连接</span></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// 文件的各种操作 </span></span><br><span class="line">    &#125; <span class="keyword">catch</span> (com.jcraft.jsch.SftpException e) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>(e.getMessage());</span><br><span class="line">    &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">        <span class="comment">// 注意这里的连接关闭</span></span><br><span class="line">        sftp.disconnect();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            sftp.getSession().disconnect();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;sftp fails to channel get session&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>


<h1 id="实战演练"><a href="#实战演练" class="headerlink" title="实战演练"></a>实战演练</h1><h2 id="配置类"><a href="#配置类" class="headerlink" title="配置类"></a>配置类</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.sduoj.judgeserver.conf;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.jcraft.jsch.*;</span><br><span class="line"><span class="keyword">import</span> com.sduoj.judgeserver.exception.internal.SftpException;</span><br><span class="line"><span class="keyword">import</span> lombok.Getter;</span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Song yang Ji</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: sduoj-judge-server</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span> 1.0</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: SFTP的配置信息类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@Slf4j(topic = &quot;SFTP&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SshConfiguration</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Getter</span></span><br><span class="line">    SshProperties sshProperties;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">SshConfiguration</span><span class="params">(SshProperties sshProperties)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.sshProperties = sshProperties;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> ChannelSftp <span class="title function_">getSftp</span><span class="params">()</span> <span class="keyword">throws</span> SftpException &#123;</span><br><span class="line">        Session session;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            session = <span class="keyword">new</span> <span class="title class_">JSch</span>().getSession(sshProperties.getUsername(), sshProperties.getHost(), sshProperties.getPort());</span><br><span class="line">            session.setConfig(<span class="string">&quot;StrictHostKeyChecking&quot;</span>, <span class="string">&quot;no&quot;</span>);</span><br><span class="line">            session.setPassword(sshProperties.getPassword());</span><br><span class="line">            session.connect();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;ssh connecting &quot;</span> + sshProperties.getUsername() + <span class="string">&quot;@&quot;</span> + sshProperties.getHost() + <span class="string">&quot; failed.&quot;</span>, e);</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        ChannelSftp sftp;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            sftp = (ChannelSftp) session.openChannel(<span class="string">&quot;sftp&quot;</span>);</span><br><span class="line">            sftp.connect();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;channel opens fail&quot;</span>, e);</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sftp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="工具类"><a href="#工具类" class="headerlink" title="工具类"></a>工具类</h2><p>接口类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.sduoj.judgeserver.util.sftp;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.nio.file.Path;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Song yang Ji</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: sduoj-judge-server</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span> 1.0</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">SftpFilesService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> problemID 题目ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> local     下载的本地的路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> SftpException Sftp 异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">downloadProblemIOFiles</span><span class="params">(String problemID, Path local)</span> <span class="keyword">throws</span> SftpException;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> problemID 题目ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> testPointID 测试点ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> local 下载的本地的路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> SftpException Sftp 异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">downloadProblemTestPointIOFiles</span><span class="params">(String problemID, String testPointID, Path local)</span> <span class="keyword">throws</span> SftpException;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<p>实现类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service(&quot;sftpFilesService&quot;)</span></span><br><span class="line"><span class="meta">@Slf4j(topic = &quot;SFTP&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SftpFilesServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">SftpFilesService</span> &#123;</span><br><span class="line"></span><br><span class="line">    EnvironmentConfig environmentConfig;</span><br><span class="line"></span><br><span class="line">    SshConfiguration sshConfiguration;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">SftpFilesServiceImpl</span><span class="params">(EnvironmentConfig environmentConfig, SshConfiguration sshConfiguration)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.environmentConfig = environmentConfig;</span><br><span class="line">        <span class="built_in">this</span>.sshConfiguration = sshConfiguration;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> problemID 题目ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> local     下载的本地的路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> SftpException Sftp 异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">downloadProblemIOFiles</span><span class="params">(String problemID, Path local)</span> <span class="keyword">throws</span> SftpException &#123;</span><br><span class="line">        <span class="comment">// 创建本地文件夹</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Files.createDirectory(local);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>(<span class="string">&quot;本地文件夹创建失败&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">String</span> <span class="variable">remoteProblemFiles</span> <span class="operator">=</span> sshConfiguration.getSshProperties().getRootDir() + problemID + <span class="string">&quot;/&quot;</span>;</span><br><span class="line">        <span class="type">ChannelSftp</span> <span class="variable">sftp</span> <span class="operator">=</span> sshConfiguration.getSftp();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            List&lt;String&gt; list = listFileNamesInDir(sftp, remoteProblemFiles);</span><br><span class="line">            <span class="keyword">for</span> (String filePath : list) &#123;</span><br><span class="line">                sftp.get(filePath, local.toString());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (com.jcraft.jsch.SftpException e) &#123;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>(e.getMessage());</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="comment">// 注意这里的连接关闭</span></span><br><span class="line">            sftp.disconnect();</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                sftp.getSession().disconnect();</span><br><span class="line">            &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">                log.error(<span class="string">&quot;sftp fails to channel get session&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> problemID   题目ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> testPointID 测试点ID</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> local       下载的本地的路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> SftpException Sftp 异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">downloadProblemTestPointIOFiles</span><span class="params">(String problemID, String testPointID, Path local)</span> <span class="keyword">throws</span> SftpException &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">remoteProblemFiles</span> <span class="operator">=</span> sshConfiguration.getSshProperties().getRootDir() + problemID + <span class="string">&quot;/&quot;</span> + testPointID + <span class="string">&quot;/&quot;</span>;</span><br><span class="line">        <span class="type">ChannelSftp</span> <span class="variable">sftp</span> <span class="operator">=</span> sshConfiguration.getSftp();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            List&lt;String&gt; list = listFileNamesInDir(sftp, remoteProblemFiles);</span><br><span class="line">            <span class="keyword">for</span> (String filePath : list) &#123;</span><br><span class="line">                sftp.get(filePath, local.toString());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (com.jcraft.jsch.SftpException e) &#123;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SftpException</span>(e.getMessage());</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="comment">// 注意这里的连接关闭</span></span><br><span class="line">            sftp.disconnect();</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                sftp.getSession().disconnect();</span><br><span class="line">            &#125; <span class="keyword">catch</span> (JSchException e) &#123;</span><br><span class="line">                log.error(<span class="string">&quot;sftp fails to channel get session&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; <span class="title function_">listFileNamesInDir</span><span class="params">(ChannelSftp sftp, String remoteDir)</span> <span class="keyword">throws</span> com.jcraft.jsch.SftpException &#123;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        Vector&lt;ChannelSftp.LsEntry&gt; ls = sftp.ls(remoteDir);</span><br><span class="line">        <span class="keyword">for</span> (ChannelSftp.LsEntry file : ls) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">filename</span> <span class="operator">=</span> file.getFilename();</span><br><span class="line">            <span class="keyword">if</span> (filename.equals(<span class="string">&quot;.&quot;</span>) || filename.equals(<span class="string">&quot;..&quot;</span>)) <span class="keyword">continue</span>;</span><br><span class="line">            list.add(remoteDir + filename);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/16/SkipList/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/16/SkipList/" class="post-title-link" itemprop="url">SkipList</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2021-12-16 14:23:04 / 修改时间：14:26:25" itemprop="dateCreated datePublished" datetime="2021-12-16T14:23:04+08:00">2021-12-16</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/" itemprop="url" rel="index"><span itemprop="name">数据结构</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="C-实现"><a href="#C-实现" class="headerlink" title="C++实现"></a>C++实现</h1><p>采用 <code>right</code>、<code>down</code>指针的方法，维护前驱与后继、上层与下层的节点之间的关系。</p>
<p><strong>缺点</strong>：每个节点都要存储真实的数据，增加了不必要的开销。</p>
<p>(<del>另外，我的代码实现有点冗余，其实可以把查找节点抽象一个方法出来。</del> )</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> std::vector;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SkipList</span> &#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="comment">// 最高层数为32层</span></span><br><span class="line">    <span class="type">static</span> <span class="type">const</span> <span class="type">int</span> MAX_LEVELS = <span class="number">32</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">Node</span> &#123;</span><br><span class="line">        <span class="comment">// 真实数据</span></span><br><span class="line">        <span class="type">int</span> val;</span><br><span class="line">        <span class="comment">// 向右走、向下走的指针</span></span><br><span class="line">        Node *right, *down;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">explicit</span> <span class="title">Node</span><span class="params">(<span class="type">int</span> val = <span class="number">0</span>, Node *right = <span class="literal">nullptr</span>, Node *down = <span class="literal">nullptr</span>)</span> : val(val), right(right), down(down) &#123;</span>&#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 哑结点</span></span><br><span class="line">    Node *head = <span class="literal">nullptr</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 模拟抛硬币</span></span><br><span class="line">    <span class="function"><span class="type">static</span> <span class="type">bool</span> <span class="title">getRand</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> x = <span class="built_in">rand</span>() % <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">return</span> x;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">SkipList</span>() &#123;</span><br><span class="line">        <span class="comment">// 哑结点初始化MAX层，next指针都为空，head是最上面的节点</span></span><br><span class="line">        <span class="comment">// 哑结点不存储任何真实数据，仅仅是为了代码实现方便罢了</span></span><br><span class="line">        Node *down = <span class="literal">nullptr</span>, *up;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; MAX_LEVELS; i++) &#123;</span><br><span class="line">            up = <span class="keyword">new</span> <span class="built_in">Node</span>(<span class="number">0</span>, <span class="literal">nullptr</span>, down);</span><br><span class="line">            down = up;</span><br><span class="line">        &#125;</span><br><span class="line">        head = up;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 查找某个元素是否存在</span></span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">search</span><span class="params">(<span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 从左上角出发</span></span><br><span class="line">        Node *node = head;</span><br><span class="line">        <span class="keyword">while</span> (node) &#123;</span><br><span class="line">            <span class="comment">//先向右移，再向下移</span></span><br><span class="line">            <span class="keyword">if</span> (node-&gt;right) &#123;</span><br><span class="line">                <span class="comment">// 此时  node.val &lt; target &lt; node.val, 通过“跳跃”的方式快速缩小了范围</span></span><br><span class="line">                <span class="keyword">if</span> (target &lt; node-&gt;right-&gt;val) &#123;</span><br><span class="line">                    node = node-&gt;down;</span><br><span class="line">                    <span class="comment">// 找到了   </span></span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (node-&gt;right-&gt;val == target) &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">                    <span class="comment">// 继续往右走    </span></span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    node = node-&gt;right;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// 右面没有节点了，只能往下走才可能找到    </span></span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                node = node-&gt;down;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 这里的新增节点，是允许重复值的；如果是Set的话，可以先查找出目标 node ，如果 node.val ==  num , 就不要重复插入了</span></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">add</span><span class="params">(<span class="type">int</span> num)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 其实是一个栈，用来存储搜索路径中的节点(前驱)，</span></span><br><span class="line">        <span class="comment">// 因为最后要根据新节点的层数往上层增加节点，就必须知道它的前驱</span></span><br><span class="line">        vector&lt;Node *&gt; downs;</span><br><span class="line">        <span class="comment">// 从顶部开始搜索。</span></span><br><span class="line">        Node *node = head;</span><br><span class="line">        <span class="keyword">while</span> (node) &#123;</span><br><span class="line">            <span class="comment">// 一直往右走，直到右边没有节点，或者右边节点的值大于 num</span></span><br><span class="line">            <span class="keyword">while</span> (node-&gt;right &amp;&amp; node-&gt;right-&gt;val &lt;= num) &#123;</span><br><span class="line">                node = node-&gt;right;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//找到这一层的找到要插入的位置的前驱, 入栈</span></span><br><span class="line">            downs.<span class="built_in">push_back</span>(node);</span><br><span class="line">            <span class="comment">// 往下走，直到最底层</span></span><br><span class="line">            node = node-&gt;down;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 这时候已经到了最底层</span></span><br><span class="line">        <span class="comment">// 从后向前根据“抛硬币的节点”依次在每一层的前驱后面插入节点;</span></span><br><span class="line">        <span class="type">int</span> pos = downs.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line">        Node *dn = <span class="literal">nullptr</span>, *pre;</span><br><span class="line">        <span class="keyword">do</span> &#123;</span><br><span class="line">            pre = downs[pos--];</span><br><span class="line">            <span class="comment">// 新增节点存储值是 num （明显数据被重复存储了），后继是 pre-&gt;right ,前驱是 pre（其实就是链表的插入操作），注意</span></span><br><span class="line">            pre-&gt;right = <span class="keyword">new</span> <span class="built_in">Node</span>(num, pre-&gt;right, dn);</span><br><span class="line">            <span class="comment">// 这时的 pre-&gt;right 就是新增的节点。</span></span><br><span class="line">            dn = pre-&gt;right;</span><br><span class="line">            <span class="comment">// 如果没有超出允许的 MAX_LEVELS 并且根据抛硬币的结果需要继续往上加，则继续  </span></span><br><span class="line">        &#125; <span class="keyword">while</span> (pos &gt;= <span class="number">0</span> &amp;&amp; <span class="built_in">getRand</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 删除一个值,基本上与查找流程一致</span></span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">erase</span><span class="params">(<span class="type">int</span> num)</span> </span>&#123;</span><br><span class="line">        Node *node = head;</span><br><span class="line">        <span class="comment">// 记录是否存在</span></span><br><span class="line">        <span class="type">bool</span> exist = <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">while</span> (node) &#123;</span><br><span class="line">            <span class="keyword">if</span> (node-&gt;right) &#123;</span><br><span class="line">                <span class="comment">// 找到了目标值</span></span><br><span class="line">                <span class="keyword">if</span> (node-&gt;right-&gt;val == num) &#123;</span><br><span class="line">                    <span class="comment">// del 即为要删除的节点</span></span><br><span class="line">                    Node *del = node-&gt;right;</span><br><span class="line">                    <span class="comment">// 链表的删除操作</span></span><br><span class="line">                    node-&gt;right = del-&gt;right;</span><br><span class="line">                    <span class="comment">// 注意我们是要把这个&quot;柱子&quot;从上向右全部删除的，所以还要往下走，继续走</span></span><br><span class="line">                    <span class="comment">// node 是要删除的节点的前驱</span></span><br><span class="line">                    node = node-&gt;down;</span><br><span class="line">                    exist = <span class="literal">true</span>;</span><br><span class="line">                    <span class="keyword">delete</span> del;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (node-&gt;right-&gt;val &lt; num) &#123;</span><br><span class="line">                    node = node-&gt;right;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    node = node-&gt;down;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                node = node-&gt;down;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> exist;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>


<h1 id="力扣《设计跳表》"><a href="#力扣《设计跳表》" class="headerlink" title="力扣《设计跳表》"></a>力扣《设计跳表》</h1><p>力扣上的一道题目，可以供你测试你的代码。<br><a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/design-skiplist/">设计跳表</a></p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span>&#123;</span><br><span class="line">    <span class="type">int</span> val;</span><br><span class="line">    Node *right, *down;</span><br><span class="line">    <span class="built_in">Node</span>(Node* _right, Node* _down, <span class="type">int</span> _val):<span class="built_in">right</span>(_right),<span class="built_in">down</span>(_down),<span class="built_in">val</span>(_val)&#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Skiplist</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    Node* head;</span><br><span class="line">    vector&lt;Node*&gt; inserted;</span><br><span class="line">    <span class="built_in">Skiplist</span>() &#123;</span><br><span class="line">        head = <span class="keyword">new</span> <span class="built_in">Node</span>(<span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">search</span><span class="params">(<span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">        Node *p = head;</span><br><span class="line">        <span class="keyword">while</span>(p)&#123;</span><br><span class="line">            <span class="keyword">while</span>(p-&gt;right &amp;&amp; p-&gt;right-&gt;val &lt; target) p = p-&gt;right;</span><br><span class="line">            <span class="keyword">if</span>(p-&gt;right &amp;&amp; p-&gt;right-&gt;val == target) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            p = p-&gt;down;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">add</span><span class="params">(<span class="type">int</span> num)</span> </span>&#123;</span><br><span class="line">        inserted.<span class="built_in">clear</span>();</span><br><span class="line">        Node *p = head;</span><br><span class="line">        <span class="keyword">while</span>(p)&#123;</span><br><span class="line">            <span class="keyword">while</span>(p-&gt;right &amp;&amp; p-&gt;right-&gt;val &lt; num) p = p-&gt;right;</span><br><span class="line">            inserted.<span class="built_in">push_back</span>(p);</span><br><span class="line">            p = p-&gt;down;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">bool</span> grow = <span class="literal">true</span>;</span><br><span class="line">        Node* downNode = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">while</span>(grow &amp;&amp; !inserted.<span class="built_in">empty</span>())&#123;</span><br><span class="line">            Node* rightmost = inserted.<span class="built_in">back</span>(); inserted.<span class="built_in">pop_back</span>();</span><br><span class="line">            Node* newNode = <span class="keyword">new</span> <span class="built_in">Node</span>(rightmost-&gt;right, downNode, num);</span><br><span class="line">            rightmost-&gt;right = newNode;</span><br><span class="line">            downNode = newNode;</span><br><span class="line">            grow = (<span class="built_in">rand</span>()%<span class="number">2</span> == <span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 不人为限制层数，层数极高的情况很稀疏；</span></span><br><span class="line">        <span class="keyword">if</span>(grow)&#123;</span><br><span class="line">            Node* newNode = <span class="keyword">new</span> <span class="built_in">Node</span>(<span class="literal">NULL</span>, downNode, num);</span><br><span class="line">            head = <span class="keyword">new</span> <span class="built_in">Node</span>(newNode, head, <span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">erase</span><span class="params">(<span class="type">int</span> num)</span> </span>&#123;</span><br><span class="line">        Node *p = head;</span><br><span class="line">        <span class="type">bool</span> seen = <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">while</span>(p)&#123;</span><br><span class="line">            <span class="keyword">while</span>(p-&gt;right &amp;&amp; p-&gt;right-&gt;val &lt; num) p = p-&gt;right;</span><br><span class="line">            <span class="keyword">if</span>(!seen &amp;&amp; p-&gt;right &amp;&amp; p-&gt;right-&gt;val == num) seen = <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">if</span>(seen)&#123;</span><br><span class="line">                p-&gt;right = p-&gt;right-&gt;right;</span><br><span class="line">            &#125;</span><br><span class="line">            p = p-&gt;down;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> seen;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Your Skiplist object will be instantiated and called as such:</span></span><br><span class="line"><span class="comment"> * Skiplist* obj = new Skiplist();</span></span><br><span class="line"><span class="comment"> * bool param_1 = obj-&gt;search(target);</span></span><br><span class="line"><span class="comment"> * obj-&gt;add(num);</span></span><br><span class="line"><span class="comment"> * bool param_3 = obj-&gt;erase(num);</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/12/16/Redis-%E9%9B%86%E7%BE%A4/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/12/16/Redis-%E9%9B%86%E7%BE%A4/" class="post-title-link" itemprop="url">Redis-集群</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-12-16 14:17:42" itemprop="dateCreated datePublished" datetime="2021-12-16T14:17:42+08:00">2021-12-16</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-03-17 02:52:40" itemprop="dateModified" datetime="2022-03-17T02:52:40+08:00">2022-03-17</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Redis/" itemprop="url" rel="index"><span itemprop="name">Redis</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="一、集群的作用"><a href="#一、集群的作用" class="headerlink" title="一、集群的作用"></a>一、集群的作用</h1><p>集群，即Redis Cluster，是Redis 3.0开始引入的分布式存储方案。</p>
<p>集群由多个节点(Node)组成，Redis的数据分布在这些节点中。</p>
<p><strong>集群中的节点分为主节点和从节点</strong>：</p>
<p><strong>只有主节点负责读写请求和集群信息的维护；从节点只进行主节点数据和状态信息的复制</strong>。</p>
<p>集群的作用，可以归纳为两点：</p>
<ol>
<li><strong>数据分区</strong>：数据分区(或称数据分片)是集群最核心的功能。</li>
</ol>
<p>集群将数据分散到多个节点，一方面突破了Redis单机内存大小的限制，<strong>存储容量大大增加</strong>；</p>
<p>另一方面每个主节点都可以对外提供读服务和写服务，<strong>大大提高了集群的响应能力</strong>。</p>
<blockquote>
<p>Redis单机内存大小受限问题，在介绍持久化和主从复制时都有提及；例如，如果单机内存太大，bgsave和bgrewriteaof的fork操作可能导致主进程阻塞，主从环境下主机切换时可能导致从节点长时间无法提供服务，全量复制阶段主节点的复制缓冲区可能溢出……。</p>
</blockquote>
<ol start="2">
<li><strong>高可用</strong>：<strong>集群支持主从复制和主节点的自动故障转移</strong>（与哨兵类似）；当<strong>任一节点发生故障时，集群仍然可以对外提供服务</strong>。</li>
</ol>
<h1 id="二、集群的基本原理"><a href="#二、集群的基本原理" class="headerlink" title="二、集群的基本原理"></a>二、集群的基本原理</h1><p>数据分区有顺序分区、哈希分区等，其中哈希分区由于其天然的随机性，使用广泛；集群的分区方案便是哈希分区的一种。</p>
<p>哈希分区的基本思路是：对数据的特征值（如key）进行哈希，然后根据哈希值决定数据落在哪个节点。常见的哈希分区包括：哈希取余分区、一致性哈希分区、带虚拟节点的一致性哈希分区等。</p>
<p>衡量数据分区方法好坏的标准有很多，其中比较重要的两个因素是(1)数据分布是否均匀(2)增加或删减节点对数据分布的影响。由于哈希的随机性，哈希分区基本可以保证数据分布均匀；因此在比较哈希分区方案时，重点要看增减节点对数据分布的影响。</p>
<p>（1）<strong>哈希取余分区</strong></p>
<p>哈希取余分区思路非常简单：计算key的hash值，然后对节点数量进行取余，从而决定数据映射到哪个节点上。该方案最大的问题是，当新增或删减节点时，节点数量发生变化，系统中所有的数据都需要重新计算映射关系，引发大规模数据迁移。</p>
<p>（2）<strong>一致性哈希分区</strong></p>
<p>一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环，如下图所示，范围为0-2^32-1；对于每个数据，根据key计算hash值，确定数据在环上的位置，然后从此位置沿环顺时针行走，找到的第一台服务器就是其应该映射到的服务器。</p>
<p>与哈希取余分区相比，一致性哈希分区将增减节点的影响限制在相邻节点。以上图为例，如果在node1和node2之间增加node5，则只有node2中的一部分数据会迁移到node5；如果去掉node2，则原node2中的数据只会迁移到node4中，只有node4会受影响。</p>
<p>一致性哈希分区的主要问题在于，当节点数量较少时，增加或删减节点，对单个节点的影响可能很大，造成数据的严重不平衡。还是以上图为例，如果去掉node2，node4中的数据由总数据的1&#x2F;4左右变为1&#x2F;2左右，与其他节点相比负载过高。此时可以将一个真实节点映射成多个虚拟节点，然后将多个虚拟节点分布到哈希环上。</p>
<p>（3）<strong>哈希槽</strong></p>
<p>该方案在一致性哈希分区的基础上，引入了虚拟节点的概念。<strong>Redis集群使用的便是该方案，其中的虚拟节点称为槽（slot）。</strong>槽是介于数据和实际节点之间的虚拟概念；每个实际节点包含一定数量的槽，每个槽包含哈希值在一定范围内的数据。引入槽以后，数据的映射关系由<strong>数据hash-&gt;实际节点</strong>，变成了<strong>数据hash-&gt;槽-&gt;实际节点</strong>。</p>
<p><strong>在使用了槽的一致性哈希分区中，槽是数据管理和迁移的基本单位。槽解耦了数据和实际节点之间的关系，增加或删除节点对系统的影响很小。</strong>仍以上图为例，系统中有4个实际节点，假设为其分配16个槽(0-15)； 槽0-3位于node1，4-7位于node2，以此类推。如果此时删除node2，只需要将槽4-7重新分配即可，例如槽4-5分配给node1，槽6分配给node3，槽7分配给node4；可以看出删除node2后，数据在其他节点的分布仍然较为均衡。</p>
<p>槽的数量一般远小于2^32，远大于实际节点的数量；在Redis集群中，槽的数量为<strong>16384</strong>。</p>
<p>下面这张图很好的总结了Redis集群将数据映射到实际节点的过程：</p>
<p><img src="/2021/12/16/Redis-%E9%9B%86%E7%BE%A4/hash-slot.png"></p>
<p>（1）Redis对数据的特征值（一般是key）计算哈希值，使用的算法是CRC16。</p>
<p>（2）根据哈希值，计算数据属于哪个槽。</p>
<p>（3）根据槽与节点的映射关系，计算数据属于哪个节点。</p>
<h1 id="三、实践须知"><a href="#三、实践须知" class="headerlink" title="三、实践须知"></a>三、实践须知</h1><h2 id="1-集群伸缩"><a href="#1-集群伸缩" class="headerlink" title="1. 集群伸缩"></a>1. 集群伸缩</h2><p>实践中常常需要对集群进行伸缩，如访问量增大时的扩容操作。Redis集群可以在不影响对外服务的情况下实现伸缩；<strong>伸缩的核心是槽迁移：修改槽与节点的对应关系，实现槽(即数据)在节点之间的移动。</strong></p>
<p>例如，如果槽均匀分布在集群的3个节点中，此时增加一个节点，则需要从3个节点中分别拿出一部分槽给新节点，从而实现槽在4个节点中的均匀分布。</p>
<h3 id="增加节点"><a href="#增加节点" class="headerlink" title="增加节点"></a>增加节点</h3><p>假设要增加7003和8003节点，其中8003是7003的从节点；步骤如下：</p>
<p>（1）<strong>启动节点</strong>：方法参见集群搭建</p>
<p>（2）<strong>节点握手</strong>：可以使用<code>cluster meet</code>命令，但在生产环境中建议使用redis-trib.rb的add-node工具，其原理也是cluster meet，但它会先检查新节点是否已加入其它集群或者存在数据，避免加入到集群后带来混乱。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-trib.rb ``add``-node 192.168.72.128:7003 192.168.72.128 7000``redis-trib.rb ``add``-node 192.168.72.128:8003 192.168.72.128 7000</span><br></pre></td></tr></table></figure>

<p>（3）<strong>迁移槽</strong>：推荐使用redis-trib.rb的reshard工具实现。reshard自动化程度很高，只需要输入**redis-trib.rb reshard ip:port (ip和port可以是集群中的任一节点)**，然后按照提示输入以下信息，槽迁移会自动完成：</p>
<ul>
<li>待迁移的槽数量：16384个槽均分给4个节点，每个节点4096个槽，因此待迁移槽数量为4096</li>
<li>目标节点id：7003节点的id</li>
<li>源节点的id：7000&#x2F;7001&#x2F;7002节点的id</li>
</ul>
<p>（4）<strong>指定主从关系</strong>：方法参见集群搭建</p>
<h3 id="减少节点"><a href="#减少节点" class="headerlink" title="减少节点"></a>减少节点</h3><p>假设要下线7000&#x2F;8000节点，可以分为两步：</p>
<p>（1）<strong>迁移槽</strong>：使用reshard将7000节点中的槽均匀迁移到7001&#x2F;7002&#x2F;7003节点</p>
<p>（2）<strong>下线节点</strong>：使用redis-trib.rb del-node工具；应先下线从节点再下线主节点，因为若主节点先下线，从节点会被指向其他主节点，造成不必要的全量复制。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">redis-trib.rb del-node 192.168.72.128:7001 &#123;节点8000的id&#125;</span><br><span class="line">redis-trib.rb del-node 192.168.72.128:7001 &#123;节点7000的id&#125;</span><br></pre></td></tr></table></figure>



<h3 id="ASK错误"><a href="#ASK错误" class="headerlink" title="ASK错误"></a>ASK错误</h3><p>集群伸缩的核心是槽迁移。在槽迁移过程中，如果客户端向源节点发送命令，源节点执行流程如下：</p>
<p><img src="/2021/12/16/Redis-%E9%9B%86%E7%BE%A4/1174710-20181025213612837-648236990.png" alt="img"></p>
<p>图片来源：《Redis设计与实现》</p>
<p>客户端收到ASK错误后，从中读取目标节点的地址信息，并向目标节点重新发送请求，就像收到MOVED错误时一样。但是二者有很大区别：ASK错误说明数据正在迁移，不知道何时迁移完成，因此重定向是临时的，SMART客户端不会刷新slots缓存；MOVED错误重定向则是(相对)永久的，SMART客户端会刷新slots缓存。</p>
<h2 id="2-故障转移"><a href="#2-故障转移" class="headerlink" title="2. 故障转移"></a>2. 故障转移</h2><p>在 《哨兵》一文中，介绍了哨兵实现故障发现和故障转移的原理。</p>
<p>虽然细节上有很大不同，但集群的实现与哨兵思路类似：<strong>通过定时任务发送PING消息检测其他节点状态；节点下线分为主观下线和客观下线；客观下线后选取从节点进行故障转移</strong>。</p>
<p><strong>与哨兵一样，集群只实现了主节点的故障转移</strong>；</p>
<p><strong>从节点故障时只会被下线，不会进行故障转移</strong>。因此，使用集群时，应谨慎使用读写分离技术，因为从节点故障会导致读服务不可用，可用性变差。</p>
<p>这里不再详细介绍故障转移的细节，只对重要事项进行说明：</p>
<p><strong>节点数量：</strong>在故障转移阶段，需要由主节点投票选出哪个从节点成为新的主节点；从节点选举胜出需要的票数为N&#x2F;2+1；其中N为主节点数量(包括故障主节点)，但故障主节点实际上不能投票。因此为了能够在故障发生时顺利选出从节点，集群中至少需要3个主节点(且部署在不同的物理机上)。</p>
<p><strong>故障转移时间：</strong>从主节点故障发生到完成转移，所需要的时间主要消耗在主观下线识别、主观下线传播、选举延迟等几个环节；具体时间与参数cluster-node-timeout有关，一般来说：</p>
<p>故障转移时间(毫秒) ≤ 1.5 * cluster-node-timeout + 1000</p>
<p>cluster-node-timeout的默认值为15000ms(15s)，因此故障转移时间会在20s量级。</p>
<h2 id="3-集群的限制及应对方法"><a href="#3-集群的限制及应对方法" class="headerlink" title="3. 集群的限制及应对方法"></a>3. 集群的限制及应对方法</h2><p>由于集群中的数据分布在不同节点中，导致一些功能受限，包括：</p>
<p>（1）key批量操作受限：例如mget、mset操作，只有当操作的key都位于一个槽时，才能进行。针对该问题，一种思路是在客户端记录槽与key的信息，每次针对特定槽执行mget&#x2F;mset；另外一种思路是使用Hash Tag，将在下一小节介绍。</p>
<p>（2）keys&#x2F;flushall等操作：keys&#x2F;flushall等操作可以在任一节点执行，但是结果只针对当前节点，例如keys操作只返回当前节点的所有键。针对该问题，可以在客户端使用cluster nodes获取所有节点信息，并对其中的所有主节点执行keys&#x2F;flushall等操作。</p>
<p>（3）事务&#x2F;Lua脚本：集群支持事务及Lua脚本，但前提条件是所涉及的key必须在同一个节点。Hash Tag可以解决该问题。</p>
<p>（4）数据库：单机Redis节点可以支持16个数据库，集群模式下只支持一个，即db0。</p>
<p>（5）复制结构：只支持一层复制结构，不支持嵌套。</p>
<h2 id="4-Hash-Tag"><a href="#4-Hash-Tag" class="headerlink" title="4. Hash Tag"></a>4. Hash Tag</h2><p>Hash Tag原理是：<strong>当一个key包含 {}的时候，不对整个key做hash，而仅对 {}包括的字符串做hash。</strong></p>
<p><strong>Hash Tag可以让不同的key拥有相同的hash值，从而分配在同一个槽里</strong>；</p>
<p>这样针对不同key的批量操作(mget&#x2F;mset等)，以及事务、Lua脚本等都可以支持。不过Hash Tag可能会带来数据分配不均的问题，这时需要：(1)调整不同节点中槽的数量，使数据分布尽量均匀；(2)避免对热点数据使用Hash Tag，导致请求分布不均。</p>
<p>下面是使用Hash Tag的一个例子；通过对product加Hash Tag，可以将所有产品信息放到同一个槽中，便于操作。</p>
<p><img src="/2021/12/16/Redis-%E9%9B%86%E7%BE%A4/1174710-20181025213630192-1534783794.png" alt="img"></p>
<h2 id="5-参数优化"><a href="#5-参数优化" class="headerlink" title="5. 参数优化"></a>5. 参数优化</h2><h3 id="cluster-node-timeout"><a href="#cluster-node-timeout" class="headerlink" title="cluster_node_timeout"></a>cluster_node_timeout</h3><p>cluster_node_timeout参数在前面已经初步介绍；它的默认值是15s，影响包括：</p>
<p>（1）影响PING消息接收节点的选择：值越大对延迟容忍度越高，选择的接收节点越少，可以降低带宽，但会降低收敛速度；应根据带宽情况和应用要求进行调整。</p>
<p>（2）影响故障转移的判定和时间：值越大，越不容易误判，但完成转移消耗时间越长；应根据网络状况和应用要求进行调整。</p>
<h3 id="cluster-require-full-coverage"><a href="#cluster-require-full-coverage" class="headerlink" title="cluster-require-full-coverage"></a>cluster-require-full-coverage</h3><p>前面提到，只有当16384个槽全部分配完毕时，集群才能上线。这样做是为了保证集群的完整性，但同时也带来了新的问题：当主节点发生故障而故障转移尚未完成，原主节点中的槽不在任何节点中，此时会集群处于下线状态，无法响应客户端的请求。</p>
<p>cluster-require-full-coverage参数可以改变这一设定：如果设置为no，则当槽没有完全分配时，集群仍可以上线。参数默认值为yes，如果应用对可用性要求较高，可以修改为no，但需要自己保证槽全部分配。</p>
<h2 id="6-redis-trib-rb"><a href="#6-redis-trib-rb" class="headerlink" title="6. redis-trib.rb"></a>6. redis-trib.rb</h2><p>redis-trib.rb提供了众多实用工具：创建集群、增减节点、槽迁移、检查完整性、数据重新平衡等；通过help命令可以查看详细信息。在实践中如果能使用redis-trib.rb工具则尽量使用，不但方便快捷，还可以大大降低出错概率。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" title="上一页" aria-label="上一页" href="/page/13/"><i class="fa fa-angle-left"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/13/">13</a><span class="page-number current">14</span><a class="page-number" href="/page/15/">15</a><span class="space">&hellip;</span><a class="page-number" href="/page/26/">26</a><a class="extend next" rel="next" title="下一页" aria-label="下一页" href="/page/15/"><i class="fa fa-angle-right"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">SongyangJi</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>
  <div class="sidebar-dimmer"></div>
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>





  





</body>
</html>
